[Commits] c75cbc1: MDEV-717 LP:1003679 - Wrong binlog order on concurrent DROP schema and

Alexey Botchkov holyfoot at askmonty.org
Tue May 3 12:21:37 EEST 2016


revision-id: c75cbc19806223be8e750c27ba0bd4b17ef61f54 (mariadb-10.1.13-24-gc75cbc1)
parent(s): 94cd0f6c9b3b04db67501ef29d470f32527ceda2
committer: Alexey Botchkov
timestamp: 2016-05-03 13:20:12 +0400
message:

MDEV-717 LP:1003679 - Wrong binlog order on concurrent DROP schema and
CREATE function.

        Test case added. That required setting some DEBUG_SYNC points.

---
 mysql-test/suite/binlog/r/binlog_mdev717.result | 40 ++++++++++++++++++++
 mysql-test/suite/binlog/t/binlog_mdev717.test   | 49 +++++++++++++++++++++++++
 sql/events.cc                                   |  5 +++
 sql/sp.cc                                       |  2 +
 sql/sql_db.cc                                   |  2 +
 5 files changed, 98 insertions(+)

diff --git a/mysql-test/suite/binlog/r/binlog_mdev717.result b/mysql-test/suite/binlog/r/binlog_mdev717.result
new file mode 100644
index 0000000..046e0ee
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_mdev717.result
@@ -0,0 +1,40 @@
+RESET MASTER;
+DROP DATABASE IF EXISTS mysqltest;
+CREATE DATABASE mysqltest;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked WAIT_FOR release";
+DROP DATABASE mysqltest;;
+SET DEBUG_SYNC= "now WAIT_FOR locked";
+SET DEBUG_SYNC= "sp_create_routine_started SIGNAL release";
+CREATE FUNCTION mysqltest.f1() RETURNS INT RETURN 1;
+CREATE DATABASE mysqltest;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked1 WAIT_FOR release1";
+DROP DATABASE mysqltest;;
+SET DEBUG_SYNC= "now WAIT_FOR locked1";
+SET DEBUG_SYNC= "create_event_started SIGNAL release1";
+CREATE EVENT mysqltest.e1 ON SCHEDULE EVERY 15 MINUTE DO BEGIN END;
+CREATE DATABASE mysqltest;
+CREATE EVENT mysqltest.e1 ON SCHEDULE EVERY 15 MINUTE DO BEGIN END;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked1 WAIT_FOR release1";
+DROP DATABASE mysqltest;;
+SET DEBUG_SYNC= "now WAIT_FOR locked1";
+SET DEBUG_SYNC= "update_event_started SIGNAL release1";
+ALTER EVENT mysqltest.e1 ON SCHEDULE EVERY 20 MINUTE DO BEGIN END;
+SET DEBUG_SYNC= "RESET";
+include/show_binlog_events.inc
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	DROP DATABASE IF EXISTS mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	CREATE DATABASE mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	DROP DATABASE mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	CREATE DATABASE mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	DROP DATABASE mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	CREATE DATABASE mysqltest
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	use `test`; CREATE DEFINER=`root`@`localhost` EVENT mysqltest.e1 ON SCHEDULE EVERY 15 MINUTE DO BEGIN END
+master-bin.000001	#	Gtid	#	#	GTID #-#-#
+master-bin.000001	#	Query	#	#	DROP DATABASE mysqltest
diff --git a/mysql-test/suite/binlog/t/binlog_mdev717.test b/mysql-test/suite/binlog/t/binlog_mdev717.test
new file mode 100644
index 0000000..5e8cce6
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_mdev717.test
@@ -0,0 +1,49 @@
+# MDEV-717 LP:1003679 - Wrong binlog order on concurrent DROP schema and CREATE function.
+
+--source include/have_log_bin.inc
+RESET MASTER;
+
+disable_warnings;
+DROP DATABASE IF EXISTS mysqltest;
+enable_warnings;
+
+connect(con1,localhost,root,,);
+connection default;
+
+CREATE DATABASE mysqltest;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked WAIT_FOR release";
+--send DROP DATABASE mysqltest;
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR locked";
+SET DEBUG_SYNC= "sp_create_routine_started SIGNAL release";
+--error 0,ER_BAD_DB_ERROR
+CREATE FUNCTION mysqltest.f1() RETURNS INT RETURN 1;
+connection default;
+--reap
+
+CREATE DATABASE mysqltest;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked1 WAIT_FOR release1";
+--send DROP DATABASE mysqltest;
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR locked1";
+SET DEBUG_SYNC= "create_event_started SIGNAL release1";
+--error 0,ER_BAD_DB_ERROR
+CREATE EVENT mysqltest.e1 ON SCHEDULE EVERY 15 MINUTE DO BEGIN END;
+connection default;
+--reap
+
+CREATE DATABASE mysqltest;
+CREATE EVENT mysqltest.e1 ON SCHEDULE EVERY 15 MINUTE DO BEGIN END;
+SET DEBUG_SYNC= "wait_drop_db_name_locked SIGNAL locked1 WAIT_FOR release1";
+--send DROP DATABASE mysqltest;
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR locked1";
+SET DEBUG_SYNC= "update_event_started SIGNAL release1";
+--error 0,ER_BAD_DB_ERROR
+ALTER EVENT mysqltest.e1 ON SCHEDULE EVERY 20 MINUTE DO BEGIN END;
+connection default;
+--reap
+
+SET DEBUG_SYNC= "RESET";
+--source include/show_binlog_events.inc
+
diff --git a/sql/events.cc b/sql/events.cc
index 77dbb8b..3c50d6e 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -333,6 +333,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data)
   if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
     DBUG_RETURN(TRUE);
 
+  DEBUG_SYNC(thd, "create_event_started");
+
   if (lock_object_name(thd, MDL_key::EVENT,
                        parse_data->dbname.str, parse_data->name.str))
     DBUG_RETURN(TRUE);
@@ -454,6 +456,9 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
 
   if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
     DBUG_RETURN(TRUE);
+
+  DEBUG_SYNC(thd, "update_event_started");
+
   if (lock_object_name(thd, MDL_key::EVENT,
                        parse_data->dbname.str, parse_data->name.str))
     DBUG_RETURN(TRUE);
diff --git a/sql/sp.cc b/sql/sp.cc
index a518b52..c2e3fd2 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1043,6 +1043,8 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
   DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
               type == TYPE_ENUM_FUNCTION);
 
+  DEBUG_SYNC(thd, "sp_create_routine_started");
+
   /* Grab an exclusive MDL lock. */
   if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str))
   {
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 2ba67cb..fdb49f2 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -837,6 +837,8 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
   if (lock_schema_name(thd, dbnorm))
     DBUG_RETURN(true);
 
+  DEBUG_SYNC(thd, "wait_drop_db_name_locked");
+
   length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
   strmov(path+length, MY_DB_OPT_FILE);		// Append db option file name
   del_dbopt(path);				// Remove dboption hash entry


More information about the commits mailing list