[MDEV-11169] Error Restoring mysqldump in MariaDB 5.5 Created: 2016-10-28  Updated: 2023-11-16  Resolved: 2023-11-16

Status: Closed
Project: MariaDB Server
Component/s: Parser, Scripts & Clients
Affects Version/s: 5.5.52
Fix Version/s: 10.6.8, 10.7.4, 10.8.3

Type: Bug Priority: Minor
Reporter: Jamie Jackson Assignee: Vladislav Vaintroub
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux; Ubuntu 12.04.5 LTS; 64-bit


Attachments: File prod_skeleton_redacted.sql    
Issue Links:
Relates
relates to MDEV-6899 extra semicolon in show create event ... Closed

 Description   

I'm getting an error restoring a mysqldump. At first, I was restoring the full dump (with data), but fortunately, I'm able to elicit the same error, on the same line, with just a structure/routine dump.

Dump

$ mysqldump -h myhost -umyuser -p --no-data --routines --single-transaction mysite_cms > /vagrant/temp/downloads/misc/prod_skeleton.sql

Restoration

$ mysql -uroot -p mysite_raw_redacted < /vagrant/temp/downloads/misc/prod_skeleton_redacted.sql
ERROR 1064 (42000) at line 1451: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '*/' at line 1

SQL

The third line (with the comments) is the problematic one.

...
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`mysite_cms`@`%`*/ /*!50003 TRIGGER cal_tbl_event_delete
AFTER DELETE ON cal_tbl_event
FOR EACH ROW
	INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.id, now(), 'cal_tbl_event'); */;;
DELIMITER ;
...

Source DB

+-------------------------+---------------------+
| Variable_name           | Value               |
+-------------------------+---------------------+
| innodb_version          | 5.5.49-MariaDB-38.0 |
| protocol_version        | 10                  |
| slave_type_conversions  |                     |
| version                 | 5.5.52-MariaDB      |
| version_comment         | MariaDB Server      |
| version_compile_machine | x86_64              |
| version_compile_os      | Linux               |
+-------------------------+---------------------+

Target DB

+-------------------------+---------------------------------+
| Variable_name           | Value                           |
+-------------------------+---------------------------------+
| innodb_version          | 5.5.52-MariaDB-38.3             |
| protocol_version        | 10                              |
| slave_type_conversions  |                                 |
| version                 | 5.5.53-MariaDB-1~precise        |
| version_comment         | mariadb.org binary distribution |
| version_compile_machine | x86_64                          |
| version_compile_os      | debian-linux-gnu                |
+-------------------------+---------------------------------+



 Comments   
Comment by Elena Stepanova [ 2016-10-28 ]

The reason of the syntax error is an extra semicolon in the trigger definition.
The question is, how it got there – in the provided dump there are several occasions, so obviously it's not a case of a highly unlikely human error.

Jamie Jackson, do you have the complete command line that was used to create the dump?

Comment by Jamie Jackson [ 2016-10-28 ]

@Elena Stepanova, the mysqldump command is included in the description.

Comment by Elena Stepanova [ 2016-10-28 ]

Okay, thanks. This command does not seem to cause an extra semicolon, so I thought maybe there was something else in there.

What does the trigger look like when you just run show create trigger cal_tbl_event_delete?
Please also attach your cnf file(s).

Comment by Jamie Jackson [ 2016-10-28 ]

$ mysql -h myhost -umyuser -p mysite_cms -e "show create trigger cal_tbl_event_delete\G"
Enter password:
*************************** 1. row ***************************
               Trigger: cal_tbl_event_delete
              sql_mode: IGNORE_SPACE
SQL Original Statement: CREATE DEFINER=`onecpd_cms`@`%` TRIGGER cal_tbl_event_delete
AFTER DELETE ON cal_tbl_event
FOR EACH ROW
        INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.id, now(), 'cal_tbl_event');
  character_set_client: utf8
  collation_connection: utf8_general_ci
    Database Collation: utf8_general_ci

Comment by Jamie Jackson [ 2016-10-28 ]

Please also attach your cnf file(s).

Source or target server?

Comment by Elena Stepanova [ 2016-10-28 ]

Source I suppose – the one where you got the output above. Normally it does not have the trailing semicolon:

*************************** 1. row ***************************
               Trigger: cal_tbl_event_delete
              sql_mode: IGNORE_SPACE
SQL Original Statement: CREATE DEFINER=`root`@`localhost` trigger cal_tbl_event_delete
AFTER DELETE ON cal_tbl_event
FOR EACH ROW
  INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
VALUES (Old.id, now(), 'cal_tbl_event')
  character_set_client: utf8
  collation_connection: utf8_general_ci
    Database Collation: utf8_general_ci
               Created: 2016-10-28 20:54:05.31

Comment by Jamie Jackson [ 2016-10-28 ]

This is from the source server (the one which I'm dumping):

/etc/my.cnf.d/server.cnf

#
# These groups are read by MariaDB server.
# Use it for options that only the server (but not clients) should see
#
# See the examples of server my.cnf files in /usr/share/mysql/
#
 
# this is read by the standalone daemon and embedded servers
[server]
 
# this is only for the mysqld standalone daemon
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
group=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=1
max_allowed_packet=16384000
group_concat_max_len=4294967295
 
innodb_buffer_pool_size=2560M
innodb_file_format = Barracuda
innodb_file_per_table = 1
 
query_cache_size=64M
query_cache_type=1
 
tmp_table_size = 16M
max_heap_table_size = 16M
 
max_connections = 1000
open_files_limit = 4096
table_cache = 4096
 
# this is only for embedded server
[embedded]
 
# This group is only read by MariaDB-5.5 servers.
# If you use the same .cnf file for MariaDB of different versions,
# use this group for options that older servers don't understand
[mysqld-5.5]
 
# These two groups are only read by MariaDB servers, not by MySQL.
# If you use the same .cnf file for MySQL and MariaDB,
# you can put MariaDB-only options here
[mariadb]
 
[mariadb-5.5]

Comment by Jamie Jackson [ 2016-10-28 ]

Linking MDEV-6899 as a potential dupe.

Comment by Jamie Jackson [ 2016-10-28 ]

FYI, I still have the create script used to create the original triggers. FWIW, it was run over JDBC (Lucee Server 4.5.4.015 and mariadb-java-client-1.2.3.jar) with `allowMultiQueries=true`.

DROP TABLE IF EXISTS delete_log;
CREATE TABLE delete_log (
  id INT NOT NULL AUTO_INCREMENT,
  deleted_id VARCHAR(35) NULL,
  deleted_date DATETIME NULL,
  deleted_table VARCHAR(100) NULL,
  deleted_type VARCHAR(100) NULL, 
  PRIMARY KEY (`id`));
 
DROP TRIGGER IF EXISTS cal_tbl_event_delete;
CREATE TRIGGER cal_tbl_event_delete
AFTER DELETE ON cal_tbl_event
FOR EACH ROW
	INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.id, now(), 'cal_tbl_event');
    
 
DROP TRIGGER IF EXISTS cal_tbl_meeting_delete;
CREATE TRIGGER cal_tbl_meeting_delete
AFTER DELETE ON cal_tbl_meeting
FOR EACH ROW
	INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.id, now(), 'cal_tbl_meeting');
    
 
DROP TRIGGER IF EXISTS cal_tbl_learning_plan_delete;
CREATE TRIGGER cal_tbl_learning_plan_delete
AFTER DELETE ON cal_tbl_learning_plan
FOR EACH ROW
	INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.id, now(), 'cal_tbl_learning_plan');
    
 
DROP TRIGGER IF EXISTS tcontent_delete;
/* since this is executed via coldfusion we don't need the delimier statement. if run with the delimiter statement, the trigger doesn't get created  */ 
/* DELIMITER $$ */
CREATE TRIGGER tcontent_delete
AFTER DELETE ON tcontent
FOR EACH ROW 
BEGIN 
	/*log the ID only if the active version no longer exists */ 
	IF NOT EXISTS (select contentid from tcontent where active = 1 and display = 1 and approved = 1 and contentID = Old.contentID) THEN
		IF Old.subType in ('News','Report') THEN
			INSERT INTO delete_log(deleted_id, deleted_date, deleted_table, deleted_type)
			VALUES (Old.ContentID, now(), 'tcontent', lcase(Old.subType));
		ELSEIF Old.subType='FAQ' THEN
			/* insert the faqID that the content is associated with */
			INSERT INTO delete_log(deleted_id, deleted_date, deleted_table, deleted_type)
			SELECT f.id, now(), 'tcontent', 'faqs'
			FROM faq_tbl_faqs f
			WHERE f.ContentID = Old.ContentID;
		END IF;
	END IF;
END;
 
/* DELIMITER ; */
 
 
/*
//delete trigger not needed for resources as they are not deleted but unpublished
DROP TRIGGER IF EXISTS rsc_tbl_resources_delete;
CREATE TRIGGER rsc_tbl_resources_delete
AFTER DELETE ON rsc_tbl_resources
FOR EACH ROW
	INSERT INTO delete_log(deleted_id, deleted_date, deleted_table)
    VALUES (Old.resource_id, now(), 'rsc_tbl_resources');
*/
 
   

Comment by Elena Stepanova [ 2016-10-28 ]

diego dupin,

Could you please take a look at the above? The SQL looks valid, and yet the server ends up with an extra semicolon at the end of the single-statement triggers. Is the connector misused here somehow, or does it actually misbehave?

Comment by Diego Dupin [ 2016-11-02 ]

Hi Elena,

After some tests, i've been able to reproduced the problem :

After query like

CREATE TRIGGER trigger_tt AFTER DELETE ON tt FOR EACH ROW DO 1; /*comment */

information_schema.TRIGGERS will contain 'DO1;'.
Without the comment everything is right (no semicolon)

Issue can be done too using the folowing command : mysql -uroot -D testj < insert.txt
with this file : (here comment works well, but not <*! > comments)

DROP TABLE IF EXISTS tt;
CREATE TABLE tt (id int);
 
DROP TRIGGER IF EXISTS trigger_tt;
DELIMITER ;;
CREATE TRIGGER trigger_tt
AFTER DELETE ON tt
FOR EACH ROW
	DO 1; /*!50003 */;;
DELIMITER ;

Comment by Elena Stepanova [ 2016-11-02 ]

diego dupin,

What you've found is MDEV-6899. It's not exactly the same problem.
In your scenario, the important part is not that there is a comment, but that there is an executable comment. You can replace it with a regular non-commented SELECT 1 for example, the result will be the same.

But as you can see in Jamie Jackson's script above, they don't have anything like that in the script – neither executable comments, nor extra statements after triggers.
Since it was executed via JDBC, the suspicion is this particular problem might be on its side.

Comment by Diego Dupin [ 2016-11-03 ]

elenst sorry i misunderstood the problem.
I've executed the query using option `allowMultiQueries=true`, and i confirm the issue : the semicolon is defined on trigger.

for example :

       try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testj?user=root&allowMultiQueries=true")) {
            Statement stmt = connection.createStatement();
            stmt.execute(
                    "DROP TABLE IF EXISTS tt;\n" +
                            "CREATE TABLE tt (id int);\n" +
                            "DROP TRIGGER IF EXISTS trigger_tt;\n" +
                            "CREATE TRIGGER trigger_tt\n" +
                            "        AFTER DELETE ON tt\n" +
                            "        FOR EACH ROW\n" +
                            "        DO 2;" +
                            "DO 1");
        }

will have a "action_statement" with "DO 2;" in I_S.TRIGGERS.

That can occur only when when option "allowMultiQueries" is enable (that correspond to capability CLIENT_MULTI_STATEMENT), permitting to send multiple statement per COM_QUERY / COM_STMT_QUERY.

SQL send is valid. Issue must lie on how server handle those multi-statement.

Comment by Daniel Black [ 2023-11-15 ]

diego dupin, with MDEV-6899 closed can this be retested.

Comment by Diego Dupin [ 2023-11-16 ]

Problem reproduced with 10.6.7 and corrected in 10.6.8.
MDEV-6899 must have correct the issue

Comment by Daniel Black [ 2023-11-16 ]

Thanks diego dupin

Generated at Thu Feb 08 07:47:50 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.