Commit 60bc62d2 authored by Luis Soares's avatar Luis Soares

BUG#54842: DROP TEMPORARY TABLE not binlogged after manual

switching binlog format to ROW

BUG 52616 fixed the case which the user would switch from STMT to
ROW binlog format, but the server would silently ignore it. After
that fix thd->is_current_stmt_binlog_format_row() reports correct
value at logging time and events are logged in ROW (as expected)
instead of STMT as they were previously and wrongly logged.

However, the fix was only partially complete, because on
disconnect, at THD cleanup, the implicit logging of temporary
tables is conditionally performed. If the binlog_format==ROW and
thd->is_current_stmt_binlog_format_row() is true then DROPs are
not logged. Given that the user can switch from STMT to ROW, this
is wrong because the server cannot tell, just by relying on the
ROW binlog format, that the tables have been dropped before. This
is effectively similar to the MIXED scenario when a switch from
STMT to ROW is triggered.

We fix this by removing this condition from
close_temporary_tables.

mysql-test/extra/binlog_tests/drop_temp_table.test:
  Added binlog test case.
mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result:
  Result changes because:
  - there is a missing drop on three temporary tables
  - it now contains results for the test added
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result:
  Result now contains the implicit drop for the temporary table.
mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result:
  Result file changed because it now contains results for added
  test case.
mysql-test/suite/rpl/r/rpl_drop_temp.result:
  Result file changed because it now contains results for added
  test case.
mysql-test/suite/rpl/t/rpl_drop_temp.test:
  Added replication test case.
sql/sql_base.cc:
  Removed the condition that would make the server to skip
  logging implicit drops when ROW binary log format mode was 
  in use.
  Additionally, deployed DBUG_ENTER/RETURN macros.
parent 11c672d0
...@@ -69,4 +69,34 @@ let $VERSION=`SELECT VERSION()`; ...@@ -69,4 +69,34 @@ let $VERSION=`SELECT VERSION()`;
source include/show_binlog_events.inc; source include/show_binlog_events.inc;
DROP DATABASE `drop-temp+table-test`; DROP DATABASE `drop-temp+table-test`;
#
# Bug #54842: DROP TEMPORARY TABLE not binlogged after manual switching binlog format to ROW
#
# Sanity test. Checking that implicit DROP event is logged.
#
# After BUG#52616, the switch to ROW mode becomes effective even
# if there are open temporary tables. As such the implicit drop
# for temporary tables on session closing must be logged.
#
RESET MASTER;
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
-- source include/show_binlog_events.inc
RESET MASTER;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -33,4 +33,23 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE I ...@@ -33,4 +33,23 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE I
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 `t` /* generated by server */
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 TEMPORARY TABLE IF EXISTS `tmp2` /* generated by server */
master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
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`; 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
show binlog events from <binlog_start>;
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;
...@@ -297,6 +297,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t0) ...@@ -297,6 +297,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t0)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb 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 `t1`,`ti`
do release_lock("lock1"); do release_lock("lock1");
drop table t0,t2; drop table t0,t2;
set autocommit=0; set autocommit=0;
......
...@@ -42,3 +42,22 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS t ...@@ -42,3 +42,22 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS t
master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
master-bin.000001 # Query # # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1` 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`; 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
show binlog events from <binlog_start>;
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 # # use `test`; CREATE TEMPORARY TABLE ttmp1 ( 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;
...@@ -26,3 +26,24 @@ CREATE TEMPORARY TABLE tmp3 (a int); ...@@ -26,3 +26,24 @@ CREATE TEMPORARY TABLE tmp3 (a int);
DROP TEMPORARY TABLE tmp3; DROP TEMPORARY TABLE tmp3;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE; START SLAVE;
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t1 ( i INT );
SHOW STATUS LIKE 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
CREATE TEMPORARY TABLE ttmp1 ( i INT );
SET SESSION binlog_format=ROW;
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 `test`; CREATE TABLE t1 ( i INT )
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE ttmp1 ( i INT )
master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1`
DROP TABLE t1;
...@@ -66,4 +66,32 @@ START SLAVE; ...@@ -66,4 +66,32 @@ START SLAVE;
connection master; connection master;
sync_slave_with_master; sync_slave_with_master;
#
# BUG#54842: DROP TEMPORARY TABLE not binlogged after manual switching binlog format to ROW
#
-- connection master
-- source include/master-slave-reset.inc
-- connection master
CREATE TABLE t1 ( i INT );
--sync_slave_with_master
SHOW STATUS LIKE 'Slave_open_temp_tables';
--connect(con1,localhost,root,,)
CREATE TEMPORARY TABLE ttmp1 ( i INT );
SET SESSION binlog_format=ROW;
--disconnect con1
-- connection master
--let $wait_binlog_event= DROP
--source include/wait_for_binlog_event.inc
--sync_slave_with_master
SHOW STATUS LIKE 'Slave_open_temp_tables';
--connection master
--source include/show_binlog_events.inc
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -1636,6 +1636,7 @@ static inline uint tmpkeyval(THD *thd, TABLE *table) ...@@ -1636,6 +1636,7 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
void close_temporary_tables(THD *thd) void close_temporary_tables(THD *thd)
{ {
DBUG_ENTER("close_temporary_tables");
TABLE *table; TABLE *table;
TABLE *next= NULL; TABLE *next= NULL;
TABLE *prev_table; TABLE *prev_table;
...@@ -1643,10 +1644,9 @@ void close_temporary_tables(THD *thd) ...@@ -1643,10 +1644,9 @@ void close_temporary_tables(THD *thd)
bool was_quote_show= TRUE; bool was_quote_show= TRUE;
if (!thd->temporary_tables) if (!thd->temporary_tables)
return; DBUG_VOID_RETURN;
if (!mysql_bin_log.is_open() || if (!mysql_bin_log.is_open())
(thd->is_current_stmt_binlog_format_row() && thd->variables.binlog_format == BINLOG_FORMAT_ROW))
{ {
TABLE *tmp_next; TABLE *tmp_next;
for (table= thd->temporary_tables; table; table= tmp_next) for (table= thd->temporary_tables; table; table= tmp_next)
...@@ -1655,7 +1655,7 @@ void close_temporary_tables(THD *thd) ...@@ -1655,7 +1655,7 @@ void close_temporary_tables(THD *thd)
close_temporary(table, 1, 1); close_temporary(table, 1, 1);
} }
thd->temporary_tables= 0; thd->temporary_tables= 0;
return; DBUG_VOID_RETURN;
} }
/* Better add "if exists", in case a RESET MASTER has been done */ /* Better add "if exists", in case a RESET MASTER has been done */
...@@ -1771,6 +1771,7 @@ void close_temporary_tables(THD *thd) ...@@ -1771,6 +1771,7 @@ void close_temporary_tables(THD *thd)
if (!was_quote_show) if (!was_quote_show)
thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0; thd->temporary_tables=0;
DBUG_VOID_RETURN;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment