mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
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.
This commit is contained in:
parent
759aabe371
commit
bf261cdb6f
7 changed files with 123 additions and 4 deletions
|
@ -69,4 +69,34 @@ let $VERSION=`SELECT VERSION()`;
|
|||
source include/show_binlog_events.inc;
|
||||
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
|
||||
|
|
|
@ -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 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 /*!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
|
||||
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)
|
|||
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 `t1`,`ti`
|
||||
do release_lock("lock1");
|
||||
drop table t0,t2;
|
||||
set autocommit=0;
|
||||
|
|
|
@ -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 /*!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
|
||||
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);
|
|||
DROP TEMPORARY TABLE tmp3;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
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;
|
|||
connection 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
|
||||
|
|
|
@ -1636,6 +1636,7 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
|
|||
|
||||
void close_temporary_tables(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("close_temporary_tables");
|
||||
TABLE *table;
|
||||
TABLE *next= NULL;
|
||||
TABLE *prev_table;
|
||||
|
@ -1643,10 +1644,9 @@ void close_temporary_tables(THD *thd)
|
|||
bool was_quote_show= TRUE;
|
||||
|
||||
if (!thd->temporary_tables)
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (!mysql_bin_log.is_open() ||
|
||||
(thd->is_current_stmt_binlog_format_row() && thd->variables.binlog_format == BINLOG_FORMAT_ROW))
|
||||
if (!mysql_bin_log.is_open())
|
||||
{
|
||||
TABLE *tmp_next;
|
||||
for (table= thd->temporary_tables; table; table= tmp_next)
|
||||
|
@ -1655,7 +1655,7 @@ void close_temporary_tables(THD *thd)
|
|||
close_temporary(table, 1, 1);
|
||||
}
|
||||
thd->temporary_tables= 0;
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* Better add "if exists", in case a RESET MASTER has been done */
|
||||
|
@ -1771,6 +1771,7 @@ void close_temporary_tables(THD *thd)
|
|||
if (!was_quote_show)
|
||||
thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
|
||||
thd->temporary_tables=0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue