diff options
-rw-r--r-- | mysql-test/r/drop_temp_table.result | 2 | ||||
-rw-r--r-- | mysql-test/r/mix_innodb_myisam_binlog.result | 2 | ||||
-rw-r--r-- | mysql-test/r/rpl_drop_temp.result | 7 | ||||
-rw-r--r-- | mysql-test/r/rpl_rewrite_db.result | 127 | ||||
-rw-r--r-- | mysql-test/t/rpl_drop_temp.test | 15 | ||||
-rw-r--r-- | mysql-test/t/rpl_rewrite_db-slave.opt | 2 | ||||
-rw-r--r-- | mysql-test/t/rpl_rewrite_db.test | 155 | ||||
-rw-r--r-- | sql/sql_base.cc | 19 |
8 files changed, 315 insertions, 14 deletions
diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/drop_temp_table.result index 96481341bd6..ff200d09de4 100644 --- a/mysql-test/r/drop_temp_table.result +++ b/mysql-test/r/drop_temp_table.result @@ -18,5 +18,5 @@ master-bin.000001 # Query 1 # create database `drop-temp+table-test` master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int) -master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`,`drop-temp+table-test`.`table:name`,`drop-temp+table-test`.`shortn1` +master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1` drop database `drop-temp+table-test`; diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index fa994363287..1f1d8795527 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -260,7 +260,7 @@ master-bin.000001 # Query # # use `test`; create table t0 (n int) master-bin.000001 # Query # # use `test`; insert t0 select * from t1 master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",null) master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti` +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t1`,`ti` do release_lock("lock1"); drop table t0,t2; reset master; diff --git a/mysql-test/r/rpl_drop_temp.result b/mysql-test/r/rpl_drop_temp.result index 04fe094ea26..fff179d7056 100644 --- a/mysql-test/r/rpl_drop_temp.result +++ b/mysql-test/r/rpl_drop_temp.result @@ -5,8 +5,15 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; create database if not exists mysqltest; +use mysqltest; create temporary table mysqltest.t1 (n int); create temporary table mysqltest.t2 (n int); +select get_lock("con_temp",10); +get_lock("con_temp",10) +1 +select get_lock("con_temp",10); +get_lock("con_temp",10) +1 show status like 'Slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 0 diff --git a/mysql-test/r/rpl_rewrite_db.result b/mysql-test/r/rpl_rewrite_db.result index 1b843bffdca..46e12bc166b 100644 --- a/mysql-test/r/rpl_rewrite_db.result +++ b/mysql-test/r/rpl_rewrite_db.result @@ -90,5 +90,132 @@ a b 2 row 2 3 row 3 0 +set sql_log_bin= 0; drop database rewrite; +set sql_log_bin= 1; +set sql_log_bin= 0; drop table t1; +set sql_log_bin= 1; + +**** +**** Bug #46861 Auto-closing of temporary tables broken by replicate-rewrite-db +**** + +**** +**** Preparing the environment +**** +SET sql_log_bin= 0; +CREATE DATABASE database_master_temp_01; +CREATE DATABASE database_master_temp_02; +CREATE DATABASE database_master_temp_03; +SET sql_log_bin= 1; +SET sql_log_bin= 0; +CREATE DATABASE database_slave_temp_01; +CREATE DATABASE database_slave_temp_02; +CREATE DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +**** +**** Creating temporary tables on different databases with different connections +**** +**** con_temp_01 --> creates +**** t_01_01_temp on database_master_temp_01 +**** +**** con_temp_02 --> creates +**** t_01_01_temp on database_master_temp_01 +**** t_02_01_temp, t_02_02_temp on database_master_temp_02 +**** +**** con_temp_02 --> creates +**** t_01_01_temp on database_master_temp_01 +**** t_02_01_temp, t_02_02_temp on database_master_temp_02 +**** t_03_01_temp, t_03_02_temp, t_03_03_temp on database_master_temp_03 +**** + +con_temp_01 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); + +con_temp_02 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); + +con_temp_03 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); +USE database_master_temp_03; +CREATE TEMPORARY TABLE t_03_01_temp(a int); +INSERT INTO t_03_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_02_temp(a int); +INSERT INTO t_03_02_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_03_temp(a int); +INSERT INTO t_03_03_temp VALUES(1); + +**** Dropping the connections +**** We want to SHOW BINLOG EVENTS, to know what was logged. But there is no +**** guarantee that logging of the terminated con1 has been done yet.a To be +**** sure that logging has been done, we use a user lock. + +show status like 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 10 +select get_lock("con_01",10); +get_lock("con_01",10) +1 +select get_lock("con_01",10); +get_lock("con_01",10) +1 +select get_lock("con_02",10); +get_lock("con_02",10) +1 +select get_lock("con_02",10); +get_lock("con_02",10) +1 +select get_lock("con_03",10); +get_lock("con_03",10) +1 +select get_lock("con_03",10); +get_lock("con_03",10) +1 + +**** Checking the binary log and temporary tables + +show status like 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 0 +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +master-bin.000001 # Query # # use `database_master_temp_02`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_02_02_temp`,`t_02_01_temp` +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +master-bin.000001 # Query # # use `database_master_temp_03`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_03_03_temp`,`t_03_02_temp`,`t_03_01_temp` +master-bin.000001 # Query # # use `database_master_temp_02`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_02_02_temp`,`t_02_01_temp` +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +**** +**** Cleaning up the test case +**** +SET sql_log_bin= 0; +DROP DATABASE database_master_temp_01; +DROP DATABASE database_master_temp_02; +DROP DATABASE database_master_temp_03; +SET sql_log_bin= 1; +SET sql_log_bin= 0; +DROP DATABASE database_slave_temp_01; +DROP DATABASE database_slave_temp_02; +DROP DATABASE database_slave_temp_03; +SET sql_log_bin= 1; diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test index 55a4e741d7c..c22bcbe63d0 100644 --- a/mysql-test/t/rpl_drop_temp.test +++ b/mysql-test/t/rpl_drop_temp.test @@ -3,15 +3,22 @@ source include/master-slave.inc; create database if not exists mysqltest; --enable_warnings +connect (con_temp,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection con_temp; +use mysqltest; create temporary table mysqltest.t1 (n int); create temporary table mysqltest.t2 (n int); -sync_slave_with_master; +select get_lock("con_temp",10); + connection master; -disconnect master; +disconnect con_temp; +select get_lock("con_temp",10); +sync_slave_with_master; + connection slave; ---real_sleep 3 # time for DROP to be written show status like 'Slave_open_temp_tables'; -connection default; +connection master; drop database mysqltest; # End of 4.1 tests diff --git a/mysql-test/t/rpl_rewrite_db-slave.opt b/mysql-test/t/rpl_rewrite_db-slave.opt index a462ad19ba0..290b92e0a3e 100644 --- a/mysql-test/t/rpl_rewrite_db-slave.opt +++ b/mysql-test/t/rpl_rewrite_db-slave.opt @@ -1 +1 @@ -"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test" +"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test" "--replicate-rewrite-db=database_master_temp_01->database_slave_temp_01" "--replicate-rewrite-db=database_master_temp_02->database_slave_temp_02" "--replicate-rewrite-db=database_master_temp_03->database_slave_temp_03" diff --git a/mysql-test/t/rpl_rewrite_db.test b/mysql-test/t/rpl_rewrite_db.test index 6b8624aff39..a9742f252be 100644 --- a/mysql-test/t/rpl_rewrite_db.test +++ b/mysql-test/t/rpl_rewrite_db.test @@ -73,9 +73,164 @@ connection slave; # The empty line last comes from the end line field in the file select * from rewrite.t1; +set sql_log_bin= 0; drop database rewrite; +set sql_log_bin= 1; connection master; +set sql_log_bin= 0; drop table t1; +set sql_log_bin= 1; # End of 4.1 tests + +--echo +--echo **** +--echo **** Bug #46861 Auto-closing of temporary tables broken by replicate-rewrite-db +--echo **** +--echo + +--echo **** +--echo **** Preparing the environment +--echo **** +connection master; + +connect (con_temp_03,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (con_temp_02,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (con_temp_01,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection master; +SET sql_log_bin= 0; +CREATE DATABASE database_master_temp_01; +CREATE DATABASE database_master_temp_02; +CREATE DATABASE database_master_temp_03; +SET sql_log_bin= 1; + +connection slave; +SET sql_log_bin= 0; +CREATE DATABASE database_slave_temp_01; +CREATE DATABASE database_slave_temp_02; +CREATE DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +--echo +--echo **** +--echo **** Creating temporary tables on different databases with different connections +--echo **** +--echo **** con_temp_01 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** +--echo **** con_temp_02 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** t_02_01_temp, t_02_02_temp on database_master_temp_02 +--echo **** +--echo **** con_temp_02 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** t_02_01_temp, t_02_02_temp on database_master_temp_02 +--echo **** t_03_01_temp, t_03_02_temp, t_03_03_temp on database_master_temp_03 +--echo **** + +--echo +--echo con_temp_01 +--echo +connection con_temp_01; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); + +--echo +--echo con_temp_02 +--echo +connection con_temp_02; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); + +--echo +--echo con_temp_03 +--echo +connection con_temp_03; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); +USE database_master_temp_03; +CREATE TEMPORARY TABLE t_03_01_temp(a int); +INSERT INTO t_03_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_02_temp(a int); +INSERT INTO t_03_02_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_03_temp(a int); +INSERT INTO t_03_03_temp VALUES(1); + +--echo +--echo **** Dropping the connections +--echo **** We want to SHOW BINLOG EVENTS, to know what was logged. But there is no +--echo **** guarantee that logging of the terminated con1 has been done yet.a To be +--echo **** sure that logging has been done, we use a user lock. +--echo +connection master; +sync_slave_with_master; +connection slave; +show status like 'Slave_open_temp_tables'; + +connection master; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +connection con_temp_01; +select get_lock("con_01",10); +connection master; +disconnect con_temp_01; +select get_lock("con_01",10); + +connection con_temp_02; +select get_lock("con_02",10); +connection master; +disconnect con_temp_02; +select get_lock("con_02",10); + +connection con_temp_03; +select get_lock("con_03",10); +connection master; +disconnect con_temp_03; +select get_lock("con_03",10); + +--echo +--echo **** Checking the binary log and temporary tables +--echo +connection master; +sync_slave_with_master; +connection slave; +show status like 'Slave_open_temp_tables'; + +connection master; +--source include/show_binlog_events.inc + +--echo **** +--echo **** Cleaning up the test case +--echo **** +connection master; +SET sql_log_bin= 0; +DROP DATABASE database_master_temp_01; +DROP DATABASE database_master_temp_02; +DROP DATABASE database_master_temp_03; +SET sql_log_bin= 1; + +connection slave; +SET sql_log_bin= 0; +DROP DATABASE database_slave_temp_01; +DROP DATABASE database_slave_temp_02; +DROP DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +connection master; +sync_slave_with_master; + +# end of 5.0 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 56ab50835b6..6a99d5d1541 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -769,19 +769,23 @@ void close_temporary_tables(THD *thd) { /* Set pseudo_thread_id to be that of the processed table */ thd->variables.pseudo_thread_id= tmpkeyval(thd, table); - /* Loop forward through all tables within the sublist of - common pseudo_thread_id to create single DROP query */ + String db; + db.append(table->s->db); + /* Loop forward through all tables that belong to a common database + within the sublist of common pseudo_thread_id to create single + DROP query + */ for (s_query.length(stub_len); table && is_user_table(table) && - tmpkeyval(thd, table) == thd->variables.pseudo_thread_id; + tmpkeyval(thd, table) == thd->variables.pseudo_thread_id && + strlen(table->s->db) == db.length() && + strcmp(table->s->db, db.ptr()) == 0; table= next) { /* - We are going to add 4 ` around the db/table names and possible more - due to special characters in the names + We are going to add ` around the table names and possible more + due to special characters */ - append_identifier(thd, &s_query, table->s->db, (uint) strlen(table->s->db)); - s_query.q_append('.'); append_identifier(thd, &s_query, table->s->table_name, (uint) strlen(table->s->table_name)); s_query.q_append(','); @@ -794,6 +798,7 @@ void close_temporary_tables(THD *thd) Query_log_event qinfo(thd, s_query.ptr(), s_query.length() - 1 /* to remove trailing ',' */, 0, FALSE, THD::NOT_KILLED); + qinfo.db= db.ptr(); thd->variables.character_set_client= cs_save; DBUG_ASSERT(qinfo.error_code == 0); mysql_bin_log.write(&qinfo); |