commit e4bb7deb77fbc9035eb0f34c45d1435f671c3dcd Author: Laurynas Biveinis Date: Tue Mar 14 15:32:33 2017 +0200 In case of CREATE ... SELECT, a temporary table is created before the logging format is decided for the current statement, resulting in premature binlog-on-drop flag value. Fix by setting the flag again, after the final decide_logging_format call. Add testcases for this and other cases of temporary table binlogging on session disconnect. diff --git a/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_row_mix.result b/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_row_mix.result new file mode 100644 index 00000000000..944dcbd4ace --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_row_mix.result @@ -0,0 +1,22 @@ +RESET MASTER; +CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=MyISAM; +SET @saved_binlog_format= @@SESSION.binlog_format; +SET SESSION binlog_format= 'STATEMENT'; +CREATE TEMPORARY TABLE tmp10 (a INT); +SET SESSION binlog_format= @saved_binlog_format; +CREATE TEMPORARY TABLE tmp1 ENGINE=InnoDB SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp2 ENGINE=MyISAM SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp3 ENGINE=MyISAM SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp4 ENGINE=InnoDB SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp5 (a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE tmp6 (a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE tmp7 LIKE t1; +CREATE TEMPORARY TABLE tmp8 LIKE t2; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; CREATE TABLE t2(a INT) ENGINE=MyISAM +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp10 (a INT) +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `tmp10` +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_stmt.result b/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_stmt.result new file mode 100644 index 00000000000..a0432263cc3 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_drop_temp_table_on_disconnect_stmt.result @@ -0,0 +1,28 @@ +RESET MASTER; +CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE tmp1 ENGINE=InnoDB SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp2 ENGINE=MyISAM SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp3 ENGINE=MyISAM SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp4 ENGINE=InnoDB SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp5 (a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE tmp6 (a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE tmp7 LIKE t1; +CREATE TEMPORARY TABLE tmp8 LIKE t2; +SET SESSION binlog_format= 'ROW'; +CREATE TEMPORARY TABLE tmp10 (a INT); +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; CREATE TABLE t2(a INT) ENGINE=MyISAM +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1 ENGINE=InnoDB SELECT * FROM t1 +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 ENGINE=MyISAM SELECT * FROM t2 +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp3 ENGINE=MyISAM SELECT * FROM t1 +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp4 ENGINE=InnoDB SELECT * FROM t2 +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp5 (a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp6 (a INT) ENGINE=MyISAM +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp7 LIKE t1 +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp8 LIKE t2 +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `tmp7`,`tmp5`,`tmp4`,`tmp1` +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `tmp8`,`tmp6`,`tmp3`,`tmp2` +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_row_mix.test b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_row_mix.test new file mode 100644 index 00000000000..03a2bf353f3 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_row_mix.test @@ -0,0 +1,36 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc +--source include/have_binlog_format_mixed_or_row.inc + +RESET MASTER; + +CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=MyISAM; + +--source include/count_sessions.inc + +--connect(con1,localhost,root) + +SET @saved_binlog_format= @@SESSION.binlog_format; +# A DROP for tmp10 should be binlogged because CREATE TABLE is +SET SESSION binlog_format= 'STATEMENT'; +CREATE TEMPORARY TABLE tmp10 (a INT); +SET SESSION binlog_format= @saved_binlog_format; + +# No DROP should be logged for any of the statements below +CREATE TEMPORARY TABLE tmp1 ENGINE=InnoDB SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp2 ENGINE=MyISAM SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp3 ENGINE=MyISAM SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp4 ENGINE=InnoDB SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp5 (a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE tmp6 (a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE tmp7 LIKE t1; +CREATE TEMPORARY TABLE tmp8 LIKE t2; + +--disconnect con1 +--connection default +--source include/wait_until_count_sessions.inc + +--source include/show_binlog_events.inc + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_stmt.test b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_stmt.test new file mode 100644 index 00000000000..c60f461e18f --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_stmt.test @@ -0,0 +1,35 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc +--source include/have_binlog_format_statement.inc + +RESET MASTER; + +CREATE TABLE t1(a INT) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=MyISAM; + +--source include/count_sessions.inc + +--connect(con1,localhost,root) + +# A DROP should be logged for the following tables because CREATE TABLE +# is logged +CREATE TEMPORARY TABLE tmp1 ENGINE=InnoDB SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp2 ENGINE=MyISAM SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp3 ENGINE=MyISAM SELECT * FROM t1; +CREATE TEMPORARY TABLE tmp4 ENGINE=InnoDB SELECT * FROM t2; +CREATE TEMPORARY TABLE tmp5 (a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE tmp6 (a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE tmp7 LIKE t1; +CREATE TEMPORARY TABLE tmp8 LIKE t2; + +SET SESSION binlog_format= 'ROW'; +# No DROP should be logged for tmp10 +CREATE TEMPORARY TABLE tmp10 (a INT); + +--disconnect con1 +--connection default +--source include/wait_until_count_sessions.inc + +--source include/show_binlog_events.inc + +DROP TABLE t1, t2; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a6bf08db120..df8c869c95a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2850,6 +2850,10 @@ int Query_result_create::prepare2() if (error) return error; + create_table->table->set_binlog_drop_if_temp( + !thd->is_current_stmt_binlog_disabled() + && !thd->is_current_stmt_binlog_format_row()); + TABLE const *const table = *tables; if (thd->is_current_stmt_binlog_format_row() && !table->s->tmp_table)