diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test index 25cbfcb7c90b..e203bda21bc3 100644 --- a/mysql-test/extra/binlog_tests/drop_temp_table.test +++ b/mysql-test/extra/binlog_tests/drop_temp_table.test @@ -67,8 +67,11 @@ connection con2; SELECT GET_LOCK("a",10); let $VERSION=`SELECT VERSION()`; -let $wait_binlog_event=DROP /*!40005 TEMPORARY */ TABLE IF EXISTS; -source include/wait_for_binlog_event.inc; +if (`SELECT @@GLOBAL.binlog_format != 'ROW'`) +{ + let $wait_binlog_event=DROP /*!40005 TEMPORARY */ TABLE IF EXISTS; + source include/wait_for_binlog_event.inc; +} source include/show_binlog_events.inc; DROP DATABASE `drop-temp+table-test`; @@ -86,27 +89,58 @@ DROP DATABASE `drop-temp+table-test`; RESET MASTER; -CREATE TABLE t1 ( i text ); +if (`SELECT @@GLOBAL.binlog_format != 'ROW'`) +{ + CREATE TABLE t1 ( i text ); + + --connect(con1,localhost,root,,) + CREATE TEMPORARY TABLE ttmp1 ( i text ); + SET @@session.binlog_format=ROW; + INSERT INTO t1 VALUES ('1'); + SELECT @@session.binlog_format; + --disconnect con1 + + -- connection default + --let $wait_binlog_event= DROP + --source include/wait_for_binlog_event.inc + --let $mask_binlog_commit_events= 1 + -- source include/show_binlog_events.inc + --let $mask_binlog_commit_events= 0 + DROP TABLE t1; + RESET MASTER; +} ---connect(con1,localhost,root,,) -CREATE TEMPORARY TABLE ttmp1 ( i text ); -SET @@session.binlog_format=ROW; -INSERT INTO t1 VALUES ('1'); -SELECT @@session.binlog_format; ---disconnect con1 +# End of 4.1 tests --- connection default ---let $wait_binlog_event= DROP ---source include/wait_for_binlog_event.inc ---let $mask_binlog_commit_events= 1 --- source include/show_binlog_events.inc ---let $mask_binlog_commit_events= 0 -RESET MASTER; +--echo # +--echo # Bug 83003: Using temporary tables on slaves increases GTID sequence number +--echo # -DROP TABLE t1; +--source include/count_sessions.inc +--connect (con1,localhost,root,,) -# End of 4.1 tests +SET @saved_binlog_format= @@SESSION.binlog_format; +SET SESSION binlog_format= STATEMENT; +CREATE TEMPORARY TABLE temp_needs_logging(a INT) ENGINE=InnoDB; +SET SESSION binlog_format= @saved_binlog_format; + +# Check with both transactional and non-transactional tables as those are logged +# separately in close_temporary_tables. +CREATE TEMPORARY TABLE temp_trx(a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE temp_non_trx(a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE temp_needs_logging_in_stmt(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 0; +CREATE TEMPORARY TABLE temp_binlog_disabled(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 1; + +--disconnect con1 +--connection default +--source include/wait_until_count_sessions.inc + +--source include/show_binlog_events.inc + +# End of 5.6 tests --echo # --echo # BUG#21638823: ASSERTION FAILED: --echo # THD->GET_TRANSACTION()->IS_EMPTY(TRANSACTION_CTX::STMT) || THD @@ -133,8 +167,11 @@ XA END 'idle_at_disconnect'; --disconnect con3 --source include/wait_until_disconnected.inc --connection default ---let $wait_binlog_event= DROP ---source include/wait_for_binlog_event.inc +if (`SELECT @@GLOBAL.binlog_format != 'ROW'`) +{ + --let $wait_binlog_event= DROP + --source include/wait_for_binlog_event.inc +} --echo # Dump binlog to show that, either the generated DROP comes after tx --echo # commit (stmt or mixed), or there is no trace of the XA txn and --echo # the temp table (row) @@ -151,4 +188,4 @@ XA ROLLBACK 'idle_when_drop_temp'; # clean up the binary log at in the end of the test # case as well. -RESET MASTER; \ No newline at end of file +RESET MASTER; diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test index 8aac9474b578..7e8e55fd5829 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test @@ -241,13 +241,16 @@ disconnect con2; # Wait until con2 disconnects --source include/wait_until_disconnected.inc connection con3; -# Bug #22084462 - MYSQL TEST BINLOG.BINLOG_ROW_MIX_INNODB_MYISAM FAILS -# Wait to ensure that drop temporary tables events -# are present in binary log. ---let $event_sequence= (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) # (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) ---let $limit= 0,4 ---let $wait_for_binlog_events= 1 ---source include/assert_binlog_events.inc +if (`SELECT @@GLOBAL.binlog_format = 'STATEMENT'`) +{ + # Bug #22084462 - MYSQL TEST BINLOG.BINLOG_ROW_MIX_INNODB_MYISAM FAILS + # Wait to ensure that drop temporary tables events + # are present in binary log. + --let $event_sequence= (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) # (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) + --let $limit= 0,4 + --let $wait_for_binlog_events= 1 + --source include/assert_binlog_events.inc +} select get_lock("lock1",60); source include/show_binlog_events.inc; do release_lock("lock1"); diff --git a/mysql-test/suite/rpl/t/rpl_gtid_disconnect_drop_temporary_table.test b/mysql-test/extra/rpl_tests/gtid_disconnect_drop_temporary_table.test similarity index 88% rename from mysql-test/suite/rpl/t/rpl_gtid_disconnect_drop_temporary_table.test rename to mysql-test/extra/rpl_tests/gtid_disconnect_drop_temporary_table.test index 577b5f1fa213..efd7bfb71af0 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_disconnect_drop_temporary_table.test +++ b/mysql-test/extra/rpl_tests/gtid_disconnect_drop_temporary_table.test @@ -92,10 +92,13 @@ while ($i <= 4) --echo # Disconnecting. --disconnect con1 - # Verify that the binlog contains the expected events. - --let $event_sequence= (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) - --let $wait_for_binlog_events= 1 - --source include/assert_binlog_events.inc + if (`SELECT @@GLOBAL.binlog_format != 'ROW'`) + { + # Verify that the binlog contains the expected events. + --let $event_sequence= (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) + --let $wait_for_binlog_events= 1 + --source include/assert_binlog_events.inc + } # Sync with slave and assert slave has dropped the temp table. --source include/sync_slave_sql_with_master.inc @@ -106,6 +109,11 @@ while ($i <= 4) # Verify that one gtid was added if gtid_mode=on --connection master --let $gtid_step_gtid_mode_agnostic= 1 + --let $gtid_step_count= 0 + if (`SELECT @@GLOBAL.binlog_format != 'ROW'`) + { + --let $gtid_step_count= 1 + } --source include/gtid_step_assert.inc --inc $i 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 000000000000..944dcbd4aced --- /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 000000000000..a0432263cc33 --- /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/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result index fb858cb361a3..2b1ab7512c7b 100644 --- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result @@ -34,26 +34,25 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE I master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS `tmp2` /* generated by server */ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `t` /* generated by server */ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `tmp2`,`t` /* generated by server */ -master-bin.000001 # Query # # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1` DROP DATABASE `drop-temp+table-test`; RESET MASTER; -CREATE TABLE t1 ( i text ); -CREATE TEMPORARY TABLE ttmp1 ( i text ); -SET @@session.binlog_format=ROW; -INSERT INTO t1 VALUES ('1'); -SELECT @@session.binlog_format; -@@session.binlog_format -ROW +# +# Bug 83003: Using temporary tables on slaves increases GTID sequence number +# +SET @saved_binlog_format= @@SESSION.binlog_format; +SET SESSION binlog_format= STATEMENT; +CREATE TEMPORARY TABLE temp_needs_logging(a INT) ENGINE=InnoDB; +SET SESSION binlog_format= @saved_binlog_format; +CREATE TEMPORARY TABLE temp_trx(a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE temp_non_trx(a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE temp_needs_logging_in_stmt(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 0; +CREATE TEMPORARY TABLE temp_binlog_disabled(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 1; 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 ( i text ) -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1` -RESET MASTER; -DROP TABLE t1; +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE temp_needs_logging(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `temp_needs_logging` # # BUG#21638823: ASSERTION FAILED: # THD->GET_TRANSACTION()->IS_EMPTY(TRANSACTION_CTX::STMT) || THD @@ -80,7 +79,6 @@ XA END 'idle_at_disconnect'; # the temp table (row) include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `temp` # # Start XA txn and leave in XA_idle XA START 'idle_when_drop_temp'; diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 91247a8f1a06..829b5ecf940d 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -261,7 +261,6 @@ set autocommit=0; create table t2 (n int) engine=innodb; insert into t2 values (3); include/save_binlog_position.inc -include/assert_binlog_events.inc [(Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*) # (Anonymous_)?Gtid # !Q(DROP.*TEMPORARY.*)] select get_lock("lock1",60); get_lock("lock1",60) 1 @@ -298,8 +297,6 @@ master-bin.000001 # Table_map # # table_id: # (test.t0) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT 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 `ti` -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t1` do release_lock("lock1"); drop table t0,t2; set autocommit=0; diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result index 244e8dd005ab..ad854fa90dda 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result @@ -60,8 +60,29 @@ master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1` -RESET MASTER; DROP TABLE t1; +RESET MASTER; +# +# Bug 83003: Using temporary tables on slaves increases GTID sequence number +# +SET @saved_binlog_format= @@SESSION.binlog_format; +SET SESSION binlog_format= STATEMENT; +CREATE TEMPORARY TABLE temp_needs_logging(a INT) ENGINE=InnoDB; +SET SESSION binlog_format= @saved_binlog_format; +CREATE TEMPORARY TABLE temp_trx(a INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE temp_non_trx(a INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE temp_needs_logging_in_stmt(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 0; +CREATE TEMPORARY TABLE temp_binlog_disabled(a INT) ENGINE=InnoDB; +SET SESSION sql_log_bin= 1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE temp_needs_logging(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE temp_trx(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE temp_non_trx(a INT) ENGINE=MyISAM +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE temp_needs_logging_in_stmt(a INT) ENGINE=InnoDB +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `temp_needs_logging_in_stmt`,`temp_trx`,`temp_needs_logging` +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `temp_non_trx` # # BUG#21638823: ASSERTION FAILED: # THD->GET_TRANSACTION()->IS_EMPTY(TRANSACTION_CTX::STMT) || THD 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 000000000000..556671e9a005 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_row_mix.test @@ -0,0 +1,60 @@ +# ====== Purpose ======= +# +# This test verifies that DROP for a temporary table created +# in Row mode is not logged in binlog at session disconnect. +# +# ====== Implementation ====== +# +# Create temporary tables in Row mode using different engines, +# also create a temporary table in Statement mode, now when you connect to the session +# after a disconnect print the output of show binlog events. +# This will verify that the DROP for temporary table created in statement +# mode is written to binary log at session disconnect, but for the temporary table +# created in Row mode no DROP statement for temporary table is logged at session +# disconnect. +# +# ====== References ======= +# +# Bug#28606948:BACKPORT OF BUG #24670909 TO 5.7.22 +# +# The name of this file has row_mix even though we are just testing in row +# format because we want the name of tests to be consistent in 5.7 and 8.0 + +--source include/have_log_bin.inc +--source include/have_myisam.inc +--source include/have_binlog_format_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 +# created in Statement mode + +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 000000000000..d8d30addf839 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_drop_temp_table_on_disconnect_stmt.test @@ -0,0 +1,56 @@ +# ====== Purpose ======= +# +# This test verifies that DROP for a temporary table created +# in Row mode is not logged in binlog at session disconnect. +# +# ====== Implementation ====== +# +# Create temporary tables in statement or mixed mode using different engines, +# also create a temporary table in Row mode, now when you connect to the session +# after a disconnect print the output of show binlog events. +# This will verify that the DROP for temporary table created in stmt or mixed +# mode is written to binary log at session disconnect, but for the temporary table +# created in Row mode no DROP statement for temporary table is logged at session +# disconnect. +# +# ====== References ======= +# +# Bug#28606948:BACKPORT OF BUG #24670909 TO 5.7.22 +# + +--source include/have_log_bin.inc +--source include/have_myisam.inc +--source include/have_binlog_format_mixed_or_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/mysql-test/suite/rpl/r/rpl_row_gtid_disconnect_drop_temporary_table.result b/mysql-test/suite/rpl/r/rpl_row_gtid_disconnect_drop_temporary_table.result new file mode 100644 index 000000000000..9c2e506831a5 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_gtid_disconnect_drop_temporary_table.result @@ -0,0 +1,62 @@ +include/master-slave.inc +Warnings: +Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. +Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. +[connection master] +CREATE TABLE t (a INT); +---- 1. Disconnect after SET GTID_NEXT ---- +include/rpl_connect.inc [creating con1] +[connection con1] +CREATE TEMPORARY TABLE tt (a INT); +SET GTID_NEXT = '#'; +include/save_binlog_position.inc +include/gtid_step_reset.inc +# Disconnecting. +include/sync_slave_sql_with_master.inc +include/assert.inc [Slave should not have any open temporary tables.] +include/gtid_step_assert.inc [count=0, only_count=0] +---- 2. Disconnect in the middle of transaction ---- +include/rpl_connect.inc [creating con1] +[connection con1] +CREATE TEMPORARY TABLE tt (a INT); +SET GTID_NEXT = '#'; +BEGIN; +INSERT INTO t VALUES (1); +include/save_binlog_position.inc +include/gtid_step_reset.inc +# Disconnecting. +include/sync_slave_sql_with_master.inc +include/assert.inc [Slave should not have any open temporary tables.] +include/gtid_step_assert.inc [count=0, only_count=0] +---- 3. Disconnect after COMMIT ---- +include/rpl_connect.inc [creating con1] +[connection con1] +CREATE TEMPORARY TABLE tt (a INT); +SET GTID_NEXT = '#'; +BEGIN; +INSERT INTO t VALUES (1); +COMMIT; +include/save_binlog_position.inc +include/gtid_step_reset.inc +# Disconnecting. +include/sync_slave_sql_with_master.inc +include/assert.inc [Slave should not have any open temporary tables.] +include/gtid_step_assert.inc [count=0, only_count=0] +---- 4. Disconnect after ROLLBACK ---- +include/rpl_connect.inc [creating con1] +[connection con1] +CREATE TEMPORARY TABLE tt (a INT); +SET GTID_NEXT = '#'; +BEGIN; +INSERT INTO t VALUES (1); +ROLLBACK; +include/save_binlog_position.inc +include/gtid_step_reset.inc +# Disconnecting. +include/sync_slave_sql_with_master.inc +include/assert.inc [Slave should not have any open temporary tables.] +include/gtid_step_assert.inc [count=0, only_count=0] +---- Clean up ---- +DROP TABLE t; +include/sync_slave_sql_with_master.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_gtid_disconnect_drop_temporary_table.result b/mysql-test/suite/rpl/r/rpl_stm_mix_gtid_disconnect_drop_temporary_table.result similarity index 100% rename from mysql-test/suite/rpl/r/rpl_gtid_disconnect_drop_temporary_table.result rename to mysql-test/suite/rpl/r/rpl_stm_mix_gtid_disconnect_drop_temporary_table.result diff --git a/mysql-test/suite/rpl/t/rpl_row_gtid_disconnect_drop_temporary_table.test b/mysql-test/suite/rpl/t/rpl_row_gtid_disconnect_drop_temporary_table.test new file mode 100644 index 000000000000..29076f636a99 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_gtid_disconnect_drop_temporary_table.test @@ -0,0 +1,8 @@ +# This is a wrapper for gtid_disconnect_drop_temporary_table.test +# so that the same test can be used for mix/statement and row mode +# The o/p of the above mentioned test varies with binlog format due to +# Bug#28606948 + +--source include/have_binlog_format_row.inc + +--source extra/rpl_tests/gtid_disconnect_drop_temporary_table.test diff --git a/mysql-test/suite/rpl/t/rpl_stm_mix_gtid_disconnect_drop_temporary_table.test b/mysql-test/suite/rpl/t/rpl_stm_mix_gtid_disconnect_drop_temporary_table.test new file mode 100644 index 000000000000..f9d510af99b5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stm_mix_gtid_disconnect_drop_temporary_table.test @@ -0,0 +1,8 @@ +# This is a wrapper for gtid_disconnect_drop_temporary_table.test +# so that the same test can be used for mix/statement and row mode +# The o/p of the above mentioned test varies with binlog format due to +# Bug#28606948 + +--source include/have_binlog_format_mixed_or_statement.inc + +--source extra/rpl_tests/gtid_disconnect_drop_temporary_table.test diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8cdd317ad91e..958246f08c34 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1945,7 +1945,7 @@ bool close_temporary_tables(THD *thd) /* scan sorted tmps to generate sequence of DROP */ for (table= thd->temporary_tables; table; table= next) { - if (is_user_table(table)) + if (is_user_table(table) && table->should_binlog_drop_if_temp()) { bool save_thread_specific_used= thd->thread_specific_used; my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id; @@ -1966,27 +1966,28 @@ bool close_temporary_tables(THD *thd) table= next) { /* Separate transactional from non-transactional temp tables */ - if (table->s->tmp_table == TRANSACTIONAL_TMP_TABLE) - { - found_trans_table= true; - /* - We are going to add ` around the table names and possible more - due to special characters - */ - append_identifier(thd, &s_query_trans, table->s->table_name.str, - strlen(table->s->table_name.str)); - s_query_trans.append(','); - } - else if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) - { - found_non_trans_table= true; - /* - We are going to add ` around the table names and possible more - due to special characters - */ - append_identifier(thd, &s_query_non_trans, table->s->table_name.str, - strlen(table->s->table_name.str)); - s_query_non_trans.append(','); + if (table->should_binlog_drop_if_temp()) { + if (table->s->tmp_table == TRANSACTIONAL_TMP_TABLE) { + found_trans_table= true; + /* + We are going to add ` around the table names and possible more + due to special characters + */ + append_identifier(thd, &s_query_trans, table->s->table_name.str, + strlen(table->s->table_name.str)); + s_query_trans.append(','); + } + else if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) + { + found_non_trans_table= true; + /* + We are going to add ` around the table names and possible more + due to special characters + */ + append_identifier(thd, &s_query_non_trans, table->s->table_name.str, + strlen(table->s->table_name.str)); + s_query_non_trans.append(','); + } } next= table->next; @@ -2069,6 +2070,7 @@ bool close_temporary_tables(THD *thd) else { next= table->next; + mysql_lock_remove(thd, thd->lock, table); close_temporary(table, 1, 1); slave_closed_temp_tables++; } @@ -6970,6 +6972,8 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, if (add_to_temporary_tables_list) { + tmp_table->set_binlog_drop_if_temp(!thd->is_current_stmt_binlog_disabled() + && !thd->is_current_stmt_binlog_format_row()); /* growing temp list at the head */ tmp_table->next= thd->temporary_tables; if (tmp_table->next) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 83f863388bd1..d8616a067354 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2804,6 +2804,10 @@ int Query_result_create::prepare2() return error; TABLE const *const table = *tables; + create_table->table->set_binlog_drop_if_temp( + !thd->is_current_stmt_binlog_disabled() + && !thd->is_current_stmt_binlog_format_row()); + if (thd->is_current_stmt_binlog_format_row() && !table->s->tmp_table) { diff --git a/sql/table.cc b/sql/table.cc index 698ed2988ee6..12bd23e4cb21 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7931,3 +7931,13 @@ void TABLE::blobs_need_not_keep_old_value() (down_cast(vfield))->set_keep_old_value(false); } } + +void TABLE::set_binlog_drop_if_temp(bool should_binlog) +{ + should_binlog_drop_if_temp_flag= should_binlog; +} + +bool TABLE::should_binlog_drop_if_temp(void) const +{ + return should_binlog_drop_if_temp_flag; +} diff --git a/sql/table.h b/sql/table.h index e7e967b982f1..246f6c76e0fb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1468,12 +1468,34 @@ struct TABLE @returns false for success, true for error */ bool contains_records(THD *thd, bool *retval); +private: + + /** + This flag decides whether or not we should log the drop temporary table + command. + */ + bool should_binlog_drop_if_temp_flag; +public: /** Virtual fields of type BLOB have a flag m_keep_old_value. This flag is set to false for all such fields in this table. */ void blobs_need_not_keep_old_value(); + + /** + Set the variable should_binlog_drop_if_temp_flag, so that + the logging of temporary tables can be decided. + + @param should_binlog the value to set flag should_binlog_drop_if_temp_flag + */ + void set_binlog_drop_if_temp(bool should_binlog); + + /** + @return whether should_binlog_drop_if_temp_flag flag is + set or not + */ + bool should_binlog_drop_if_temp(void) const; };