MDEV-5854 Interrupted CREATE OR REPLACE is written into binlog, and in a wrong format
mysql-test/r/create_or_replace2.result: Added test case mysql-test/t/create_or_replace.test: Fixed comment mysql-test/t/create_or_replace2.test: Added test case sql/sql_base.cc: Safety fix: Don't let threads with query_id=0 free temporary tables as this may free temporary tables not in use. This is mostly the case for the slave io threads, as most other threads has thd->query_id != 0. sql/sql_table.cc: Added comment. Ignore kill when opening temporary table for CREATE ... LIKE. This fixed the original isue
This commit is contained in:
parent
e7704bfdd6
commit
913d1f199c
25
mysql-test/r/create_or_replace2.result
Normal file
25
mysql-test/r/create_or_replace2.result
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
drop table if exists t1;
|
||||||
|
SET @old_debug= @@session.debug;
|
||||||
|
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=InnoDB;
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tmp (a int, b int, key(a)) engine=myisam;
|
||||||
|
set debug_dbug='+d,send_kill_after_delete';
|
||||||
|
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||||
|
set debug_dbug=@old_debug;
|
||||||
|
SHOW TABLES;
|
||||||
|
Tables_in_test
|
||||||
|
t1
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL,
|
||||||
|
KEY `a` (`a`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
SHOW TABLES;
|
||||||
|
Tables_in_test
|
||||||
|
t1
|
||||||
|
drop temporary table if exists tmp;
|
||||||
|
drop table t1;
|
||||||
|
include/rpl_end.inc
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Check CREATE OR REPLACE ALTER TABLE
|
# Check CREATE OR REPLACE TABLE
|
||||||
#
|
#
|
||||||
|
|
||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
35
mysql-test/t/create_or_replace2.test
Normal file
35
mysql-test/t/create_or_replace2.test
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#
|
||||||
|
# Check CREATE OR REPLACE TABLE for test that requires DEBUG
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/have_debug.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/have_xtradb.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
SET @old_debug= @@session.debug;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-5854
|
||||||
|
# Interrupted CREATE OR REPLACE is written into binlog, and in a wrong format
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=InnoDB;
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tmp (a int, b int, key(a)) engine=myisam;
|
||||||
|
set debug_dbug='+d,send_kill_after_delete';
|
||||||
|
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||||
|
set debug_dbug=@old_debug;
|
||||||
|
SHOW TABLES;
|
||||||
|
show create table t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
SHOW TABLES;
|
||||||
|
--connection master
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop temporary table if exists tmp;
|
||||||
|
--enable_warnings
|
||||||
|
drop table t1;
|
||||||
|
--source include/rpl_end.inc
|
@ -656,6 +656,12 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("mark_temp_tables_as_free_for_reuse");
|
DBUG_ENTER("mark_temp_tables_as_free_for_reuse");
|
||||||
|
|
||||||
|
if (thd->query_id == 0)
|
||||||
|
{
|
||||||
|
/* Thread has not executed any statement and has not used any tmp tables */
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
thd->lock_temporary_tables();
|
thd->lock_temporary_tables();
|
||||||
for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
|
for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
|
||||||
{
|
{
|
||||||
|
@ -2560,6 +2560,18 @@ err:
|
|||||||
error= 1;
|
error= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We are always logging drop of temporary tables.
|
||||||
|
The reason is to handle the following case:
|
||||||
|
- Use statement based replication
|
||||||
|
- CREATE TEMPORARY TABLE foo (logged)
|
||||||
|
- set row based replication
|
||||||
|
- DROP TEMPORAY TABLE foo (needs to be logged)
|
||||||
|
This should be fixed so that we remember if creation of the
|
||||||
|
temporary table was logged and only log it if the creation was
|
||||||
|
logged.
|
||||||
|
*/
|
||||||
|
|
||||||
if (non_trans_tmp_table_deleted ||
|
if (non_trans_tmp_table_deleted ||
|
||||||
trans_tmp_table_deleted || non_tmp_table_deleted)
|
trans_tmp_table_deleted || non_tmp_table_deleted)
|
||||||
{
|
{
|
||||||
@ -4628,6 +4640,7 @@ int create_table_impl(THD *thd,
|
|||||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||||
thd->log_current_statement= 1;
|
thd->log_current_statement= 1;
|
||||||
create_info->table_was_deleted= 1;
|
create_info->table_was_deleted= 1;
|
||||||
|
DBUG_EXECUTE_IF("send_kill_after_delete", thd->killed= KILL_QUERY; );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The test of query_tables is to ensure we have any tables in the
|
The test of query_tables is to ensure we have any tables in the
|
||||||
@ -4769,6 +4782,7 @@ int create_table_impl(THD *thd,
|
|||||||
err:
|
err:
|
||||||
THD_STAGE_INFO(thd, stage_after_create);
|
THD_STAGE_INFO(thd, stage_after_create);
|
||||||
delete file;
|
delete file;
|
||||||
|
DBUG_PRINT("exit", ("return: %d", error));
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
|
|
||||||
warn:
|
warn:
|
||||||
@ -5262,7 +5276,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
char buf[2048];
|
char buf[2048];
|
||||||
String query(buf, sizeof(buf), system_charset_info);
|
String query(buf, sizeof(buf), system_charset_info);
|
||||||
query.length(0); // Have to zero it since constructor doesn't
|
query.length(0); // Have to zero it since constructor doesn't
|
||||||
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
|
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN |
|
||||||
|
MYSQL_OPEN_IGNORE_KILLED);
|
||||||
bool new_table= FALSE; // Whether newly created table is open.
|
bool new_table= FALSE; // Whether newly created table is open.
|
||||||
|
|
||||||
if (create_res != 0)
|
if (create_res != 0)
|
||||||
@ -5271,6 +5286,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
Table or view with same name already existed and we where using
|
Table or view with same name already existed and we where using
|
||||||
IF EXISTS. Continue without logging anything.
|
IF EXISTS. Continue without logging anything.
|
||||||
*/
|
*/
|
||||||
|
do_logging= 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!table->table)
|
if (!table->table)
|
||||||
@ -5316,6 +5332,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
|
if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
|
||||||
{
|
{
|
||||||
res= 1;
|
res= 1;
|
||||||
|
do_logging= 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user