diff --git a/mysql-test/r/create_or_replace2.result b/mysql-test/r/create_or_replace2.result new file mode 100644 index 00000000000..6f5e412b91c --- /dev/null +++ b/mysql-test/r/create_or_replace2.result @@ -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 diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test index a48f7d70a17..91c6c69ff1b 100644 --- a/mysql-test/t/create_or_replace.test +++ b/mysql-test/t/create_or_replace.test @@ -1,5 +1,5 @@ # -# Check CREATE OR REPLACE ALTER TABLE +# Check CREATE OR REPLACE TABLE # --source include/have_innodb.inc diff --git a/mysql-test/t/create_or_replace2.test b/mysql-test/t/create_or_replace2.test new file mode 100644 index 00000000000..be1bd9a3d81 --- /dev/null +++ b/mysql-test/t/create_or_replace2.test @@ -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 diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bb15562b8f8..918da90e875 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -656,6 +656,12 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd) { 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(); for (TABLE *table= thd->temporary_tables ; table ; table= table->next) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bee2ad64626..8e9601c437e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2560,6 +2560,18 @@ err: 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 || 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->log_current_statement= 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 @@ -4769,6 +4782,7 @@ int create_table_impl(THD *thd, err: THD_STAGE_INFO(thd, stage_after_create); delete file; + DBUG_PRINT("exit", ("return: %d", error)); DBUG_RETURN(error); warn: @@ -5262,7 +5276,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, char buf[2048]; String query(buf, sizeof(buf), system_charset_info); 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. 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 IF EXISTS. Continue without logging anything. */ + do_logging= 0; goto err; } 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())) { res= 1; + do_logging= 0; goto err; }