Skip to content
Permalink
Browse files

BUG#28642318: POINT IN TIME RECOVERY USING MYSQLBINLOG BROKEN

              WITH TEMPORARY TABLE -> ERRORS

Analysis
========
Point in time recovery using mysqlbinlog containing queries
operating on temporary tables results in an error.

While writing the query log event in the binary log, the
thread id used for execution of DROP TABLE and DELETE commands
were incorrect. The thread variable 'thread_specific_used'
is used to determine whether a specific thread id is to used
while executing the statements i.e using 'SET
@@session.pseudo_thread_id'. This variable was not set
correctly for DROP TABLE query and was never set for DELETE
query. The thread id is important for temporary tables
since the tables are session specific. DROP TABLE and DELETE
queries executed using a wrong thread id resulted in errors
while applying the queries generated by mysqlbinlog utility.

Fix
===
Set the 'thread_specific_used' THD variable for DROP TABLE and
DELETE queries.

ReviewBoard: 21833
  • Loading branch information...
Nisha Gopalakrishnan
Nisha Gopalakrishnan committed Apr 17, 2019
1 parent 38ee3d1 commit 94499c2deba495c0b8d9729856d480c732c2475a
@@ -100,3 +100,72 @@ RESET MASTER;
DROP TABLE t1;

# End of 4.1 tests


--echo #
--echo # BUG#28642318: POINT IN TIME RECOVERY USING MYSQLBINLOG BROKEN
--echo # WITH TEMPORARY TABLE -> ERRORS

--echo # Test case for DELETE query.

RESET MASTER;
connect (con1,localhost,root,,);

--echo # Set up.
--connection default
--disable_warnings
SET @save_binlog_format= @@session.binlog_format;
SET @@session.binlog_format=STATEMENT;
let $MYSQLD_DATADIR= `select @@datadir`;
CREATE TABLE t1 (a INT) ENGINE=INNODB;

--connection con1
SET @@session.binlog_format=STATEMENT;
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;

--connection default
DELETE d1, d2 FROM t1 AS d1, t1 AS d2 WHERE d1.a<>d2.a;

--exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/bug28642318.sql

--connection default
DROP TABLE t1;

--echo # DELETE query fails with table re-open error without patch.
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug28642318.sql

--echo # Clean up.
--connection con1
DROP TABLE IF EXISTS t1;

--connection default
DROP TABLE IF EXISTS t1;
RESET MASTER;

--echo # Test case for DROP query.

--connection default
CREATE TABLE t1 (a INT) ENGINE=INNODB;

--connection con1
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;

--connection default
DROP TABLE t1;

--connection con1
DROP TABLE t1;

--connection default
--exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/bug28642318.sql

--echo # DROP table query fails with unknown table error without patch.
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug28642318.sql

--echo # Clean up
--connection default
SET @@session.binlog_format= @save_binlog_format;
RESET MASTER;

--disconnect con1
--enable_warnings
@@ -54,3 +54,30 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1`
RESET MASTER;
DROP TABLE t1;
#
# BUG#28642318: POINT IN TIME RECOVERY USING MYSQLBINLOG BROKEN
# WITH TEMPORARY TABLE -> ERRORS
# Test case for DELETE query.
RESET MASTER;
# Set up.
SET @save_binlog_format= @@session.binlog_format;
SET @@session.binlog_format=STATEMENT;
CREATE TABLE t1 (a INT) ENGINE=INNODB;
SET @@session.binlog_format=STATEMENT;
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;
DELETE d1, d2 FROM t1 AS d1, t1 AS d2 WHERE d1.a<>d2.a;
DROP TABLE t1;
# DELETE query fails with table re-open error without patch.
# Clean up.
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET MASTER;
# Test case for DROP query.
CREATE TABLE t1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;
DROP TABLE t1;
DROP TABLE t1;
# DROP table query fails with unknown table error without patch.
# Clean up
SET @@session.binlog_format= @save_binlog_format;
RESET MASTER;
@@ -62,3 +62,30 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1`
RESET MASTER;
DROP TABLE t1;
#
# BUG#28642318: POINT IN TIME RECOVERY USING MYSQLBINLOG BROKEN
# WITH TEMPORARY TABLE -> ERRORS
# Test case for DELETE query.
RESET MASTER;
# Set up.
SET @save_binlog_format= @@session.binlog_format;
SET @@session.binlog_format=STATEMENT;
CREATE TABLE t1 (a INT) ENGINE=INNODB;
SET @@session.binlog_format=STATEMENT;
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;
DELETE d1, d2 FROM t1 AS d1, t1 AS d2 WHERE d1.a<>d2.a;
DROP TABLE t1;
# DELETE query fails with table re-open error without patch.
# Clean up.
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET MASTER;
# Test case for DROP query.
CREATE TABLE t1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB;
DROP TABLE t1;
DROP TABLE t1;
# DROP table query fails with unknown table error without patch.
# Clean up
SET @@session.binlog_format= @save_binlog_format;
RESET MASTER;
@@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1081,6 +1081,7 @@ bool multi_delete::send_eof()
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
thd->thread_specific_used= TRUE;
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, FALSE, errcode) &&
@@ -1,5 +1,5 @@
/*
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2600,8 +2600,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
#endif
}
DEBUG_SYNC(thd, "rm_table_no_locks_before_binlog");
thd->thread_specific_used|= (trans_tmp_table_deleted ||
non_trans_tmp_table_deleted);
thd->thread_specific_used= TRUE;
error= 0;
err:
if (wrong_tables.length())

0 comments on commit 94499c2

Please sign in to comment.
You can’t perform that action at this time.