mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated
Merge branch '10.2' into 10.3
This commit is contained in:
32
mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result
Normal file
32
mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
create table t1 (a int) engine=innodb;
|
||||||
|
create table t2 (b longblob) engine=innodb;
|
||||||
|
create table t3 (c int) engine=innodb;
|
||||||
|
insert into t2 values (repeat('b',1024*1024));
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2';
|
||||||
|
drop table t1, t2, t3;
|
||||||
|
connect foo,localhost,root;
|
||||||
|
set debug_sync='now SIGNAL go';
|
||||||
|
kill query CONNECTION_ID;
|
||||||
|
connection master;
|
||||||
|
ERROR 70100: Query execution was interrupted
|
||||||
|
"Tables t2 and t3 should be listed"
|
||||||
|
SHOW TABLES;
|
||||||
|
Tables_in_test
|
||||||
|
t2
|
||||||
|
t3
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
|
||||||
|
connection slave;
|
||||||
|
drop table t2, t3;
|
||||||
|
connection master;
|
||||||
|
set debug_sync='RESET';
|
||||||
|
drop table t2, t3;
|
||||||
|
include/rpl_end.inc
|
64
mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test
Normal file
64
mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# ==== Purpose ====
|
||||||
|
#
|
||||||
|
# Check that when the execution of a DROP TABLE command with single table
|
||||||
|
# fails it should not be written to the binary log. Also test that when the
|
||||||
|
# execution of DROP TABLE command with multiple tables fails the command
|
||||||
|
# should be written into the binary log.
|
||||||
|
#
|
||||||
|
# ==== Implementation ====
|
||||||
|
#
|
||||||
|
# Steps:
|
||||||
|
# 0 - Create tables named t1, t2, t3
|
||||||
|
# 1 - Execute DROP TABLE t1,t2,t3 command.
|
||||||
|
# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'.
|
||||||
|
# 3 - Verify that tables t2,t3 are present after the DROP command execution
|
||||||
|
# was interrupted.
|
||||||
|
# 4 - Check that table 't1' is present in binary log as part of DROP
|
||||||
|
# command.
|
||||||
|
#
|
||||||
|
# ==== References ====
|
||||||
|
#
|
||||||
|
# MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated.
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_debug_sync.inc
|
||||||
|
--source include/have_binlog_format_statement.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
create table t1 (a int) engine=innodb;
|
||||||
|
create table t2 (b longblob) engine=innodb;
|
||||||
|
create table t3 (c int) engine=innodb;
|
||||||
|
insert into t2 values (repeat('b',1024*1024));
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
insert into t2 select * from t2;
|
||||||
|
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||||
|
|
||||||
|
let $id=`select connection_id()`;
|
||||||
|
set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2';
|
||||||
|
send drop table t1, t2, t3;
|
||||||
|
|
||||||
|
connect foo,localhost,root;
|
||||||
|
set debug_sync='now SIGNAL go';
|
||||||
|
let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%';
|
||||||
|
source include/wait_condition.inc;
|
||||||
|
--replace_result $id CONNECTION_ID
|
||||||
|
eval kill query $id;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
error ER_QUERY_INTERRUPTED;
|
||||||
|
reap;
|
||||||
|
|
||||||
|
--echo "Tables t2 and t3 should be listed"
|
||||||
|
SHOW TABLES;
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
--sync_slave_with_master
|
||||||
|
drop table t2, t3;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
set debug_sync='RESET';
|
||||||
|
drop table t2, t3;
|
||||||
|
|
||||||
|
source include/rpl_end.inc;
|
@ -2403,35 +2403,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
/* remove .frm file and engine files */
|
/* remove .frm file and engine files */
|
||||||
path_length= build_table_filename(path, sizeof(path) - 1, db.str, alias.str,
|
path_length= build_table_filename(path, sizeof(path) - 1, db.str, alias.str,
|
||||||
reg_ext, 0);
|
reg_ext, 0);
|
||||||
|
|
||||||
/*
|
|
||||||
This handles the case where a "DROP" was executed and a regular
|
|
||||||
table "may be" dropped as drop_temporary is FALSE and error is
|
|
||||||
TRUE. If the error was FALSE a temporary table was dropped and
|
|
||||||
regardless of the status of drop_temporary a "DROP TEMPORARY"
|
|
||||||
must be used.
|
|
||||||
*/
|
|
||||||
if (!dont_log_query)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Note that unless if_exists is TRUE or a temporary table was deleted,
|
|
||||||
there is no means to know if the statement should be written to the
|
|
||||||
binary log. See further information on this variable in what follows.
|
|
||||||
*/
|
|
||||||
non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted);
|
|
||||||
/*
|
|
||||||
Don't write the database name if it is the current one (or if
|
|
||||||
thd->db is NULL).
|
|
||||||
*/
|
|
||||||
if (thd->db.str == NULL || cmp(&db, &thd->db) != 0)
|
|
||||||
{
|
|
||||||
append_identifier(thd, &built_query, &db);
|
|
||||||
built_query.append(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
append_identifier(thd, &built_query, &table->table_name);
|
|
||||||
built_query.append(",");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
|
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
|
||||||
error= 0;
|
error= 0;
|
||||||
@ -2511,9 +2482,16 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
// Remove extension for delete
|
// Remove extension for delete
|
||||||
*(end= path + path_length - reg_ext_length)= '\0';
|
*(end= path + path_length - reg_ext_length)= '\0';
|
||||||
|
|
||||||
error= ha_delete_table(thd, table_type, path, &db, &table->table_name,
|
if ((error= ha_delete_table(thd, table_type, path, &db, &table->table_name,
|
||||||
!dont_log_query);
|
!dont_log_query)))
|
||||||
if (!error)
|
{
|
||||||
|
if (thd->is_killed())
|
||||||
|
{
|
||||||
|
error= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Delete the table definition file */
|
/* Delete the table definition file */
|
||||||
strmov(end,reg_ext);
|
strmov(end,reg_ext);
|
||||||
@ -2570,6 +2548,22 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
mysql_audit_drop_table(thd, table);
|
mysql_audit_drop_table(thd, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dont_log_query && !drop_temporary)
|
||||||
|
{
|
||||||
|
non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted);
|
||||||
|
/*
|
||||||
|
Don't write the database name if it is the current one (or if
|
||||||
|
thd->db is NULL).
|
||||||
|
*/
|
||||||
|
if (thd->db.str == NULL || cmp(&db, &thd->db) != 0)
|
||||||
|
{
|
||||||
|
append_identifier(thd, &built_query, &db);
|
||||||
|
built_query.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
append_identifier(thd, &built_query, &table->table_name);
|
||||||
|
built_query.append(",");
|
||||||
|
}
|
||||||
DBUG_PRINT("table", ("table: %p s: %p", table->table,
|
DBUG_PRINT("table", ("table: %p s: %p", table->table,
|
||||||
table->table ? table->table->s : NULL));
|
table->table ? table->table->s : NULL));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user