mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE
In statement-based or mixed-mode replication, use DROP TEMPORARY TABLE to drop multiple tables causes different errors on master and slave, when one or more of these tables do not exist. Because when executed on slave, it would automatically add IF EXISTS to the query to ignore all ER_BAD_TABLE_ERROR errors. To fix the problem, do not add IF EXISTS when executing DROP TEMPORARY TABLE on the slave, and clear the ER_BAD_TABLE_ERROR error after execution if the query does not expect any errors.
This commit is contained in:
commit
dbe02e6d4a
4 changed files with 57 additions and 12 deletions
|
@ -12,3 +12,17 @@ show status like 'Slave_open_temp_tables';
|
|||
Variable_name Value
|
||||
Slave_open_temp_tables 0
|
||||
drop database mysqltest;
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 'tmp1'
|
||||
CREATE TEMPORARY TABLE t1 ( a int );
|
||||
DROP TEMPORARY TABLE t1, t2;
|
||||
ERROR 42S02: Unknown table 't2'
|
||||
DROP TEMPORARY TABLE tmp2;
|
||||
ERROR 42S02: Unknown table 'tmp2'
|
||||
stop slave;
|
||||
**** On Master ****
|
||||
CREATE TEMPORARY TABLE tmp3 (a int);
|
||||
DROP TEMPORARY TABLE tmp3;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
|
|
|
@ -34,4 +34,36 @@ connection master;
|
|||
drop database mysqltest;
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# Bug#49137
|
||||
# This test verifies if DROP MULTI TEMPORARY TABLE
|
||||
# will cause different errors on master and slave,
|
||||
# when one or more of these tables do not exist.
|
||||
#
|
||||
|
||||
connection master;
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp1;
|
||||
CREATE TEMPORARY TABLE t1 ( a int );
|
||||
--error 1051
|
||||
DROP TEMPORARY TABLE t1, t2;
|
||||
--error 1051
|
||||
DROP TEMPORARY TABLE tmp2;
|
||||
sync_slave_with_master;
|
||||
|
||||
connection slave;
|
||||
stop slave;
|
||||
wait_for_slave_to_stop;
|
||||
|
||||
--echo **** On Master ****
|
||||
connection master;
|
||||
CREATE TEMPORARY TABLE tmp3 (a int);
|
||||
DROP TEMPORARY TABLE tmp3;
|
||||
|
||||
connection slave;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
|
||||
connection master;
|
||||
sync_slave_with_master;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -3171,7 +3171,17 @@ START SLAVE; . Query: '%s'", expected_error, thd->query());
|
|||
|
||||
compare_errors:
|
||||
|
||||
/*
|
||||
/*
|
||||
In the slave thread, we may sometimes execute some DROP / * 40005
|
||||
TEMPORARY * / TABLE that come from parts of binlogs (likely if we
|
||||
use RESET SLAVE or CHANGE MASTER TO), while the temporary table
|
||||
has already been dropped. To ignore such irrelevant "table does
|
||||
not exist errors", we silently clear the error if TEMPORARY was used.
|
||||
*/
|
||||
if (thd->lex->drop_temporary && thd->is_error() &&
|
||||
thd->main_da.sql_errno() == ER_BAD_TABLE_ERROR && !expected_error)
|
||||
thd->main_da.reset_diagnostics_area();
|
||||
/*
|
||||
If we expected a non-zero error code, and we don't get the same error
|
||||
code, and it should be ignored or is related to a concurrency issue.
|
||||
*/
|
||||
|
|
|
@ -3373,17 +3373,6 @@ end_with_restore_list:
|
|||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If this is a slave thread, we may sometimes execute some
|
||||
DROP / * 40005 TEMPORARY * / TABLE
|
||||
that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
|
||||
MASTER TO), while the temporary table has already been dropped.
|
||||
To not generate such irrelevant "table does not exist errors",
|
||||
we silently add IF EXISTS if TEMPORARY was used.
|
||||
*/
|
||||
if (thd->slave_thread)
|
||||
lex->drop_if_exists= 1;
|
||||
|
||||
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||
thd->options|= OPTION_KEEP_LOG;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue