From 4aee29e844b0fe1afd357db53a7897bdb570693b Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 28 Jan 2009 14:35:12 +0000 Subject: [PATCH] BUG#35583 mysqlbinlog replay fails with ERROR 1146 when temp tables are used When using CREATE TEMPORARY TABLE LIKE to create a temporary table, or using TRUNCATE to delete all rows of a temporary table, they did not set the tmp_table_used flag, and cause the omission of "SET @@session.pseudo_thread_id" when dumping binlog with mysqlbinlog, and cause error when replay the statements. This patch fixed the problem by setting tmp_table_used in these two cases. (Done by He Zhenxing 2009-01-12) --- .../suite/binlog/r/binlog_tmp_table.result | 30 +++++++ .../suite/binlog/t/binlog_tmp_table.test | 82 +++++++++++++++++++ sql/sql_delete.cc | 3 + sql/sql_table.cc | 1 + 4 files changed, 116 insertions(+) create mode 100644 mysql-test/suite/binlog/r/binlog_tmp_table.result create mode 100644 mysql-test/suite/binlog/t/binlog_tmp_table.test diff --git a/mysql-test/suite/binlog/r/binlog_tmp_table.result b/mysql-test/suite/binlog/r/binlog_tmp_table.result new file mode 100644 index 00000000000..e4928432324 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_tmp_table.result @@ -0,0 +1,30 @@ +create table foo (a int); +flush logs; +create temporary table tmp1_foo like foo; +create temporary table tmp2_foo (a int); +insert into tmp1_foo values (1), (2), (3), (4); +replace into tmp2_foo values (1), (2), (3), (4); +update tmp1_foo set a=2*a-1; +update tmp2_foo set a=2*a; +delete from tmp1_foo where a < 5; +delete from tmp2_foo where a < 5; +insert into foo select * from tmp1_foo; +insert into foo select * from tmp2_foo; +truncate table tmp1_foo; +truncate table tmp2_foo; +flush logs; +select * from foo; +a +5 +7 +6 +8 +drop table foo; +create table foo (a int); +select * from foo; +a +5 +7 +6 +8 +drop table foo; diff --git a/mysql-test/suite/binlog/t/binlog_tmp_table.test b/mysql-test/suite/binlog/t/binlog_tmp_table.test new file mode 100644 index 00000000000..961ac03e873 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_tmp_table.test @@ -0,0 +1,82 @@ +# ==== Purpose ==== +# +# Test if statements used temporary tables are binlogged correctly +# +# ==== Method ==== +# +# Use two connections, use temporary tables on both of them, and by +# switching connections between statements, the test can check if the +# statements are logged with the correct thread id. +# +# The statements current tested include: +# CREATE TEMPORARY TABLE +# CREATE TEMPORARY TABLE LIKE +# INSERT +# REPLACE +# UPDATE +# INSERT SELECT +# TRUNCATE +# +# Note: When adding new query statements, please add them between the +# two 'flush logs'. And aslo please make sure the connection is +# switched between each statement. +# +# ==== Related bugs ==== +# +# BUG#35583 mysqlbinlog replay fails with ERROR 1146 when temp tables are used +# +source include/have_log_bin.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,); + +create table foo (a int); + +flush logs; + +connection master; +create temporary table tmp1_foo like foo; +connection master1; +create temporary table tmp2_foo (a int); + +connection master; +insert into tmp1_foo values (1), (2), (3), (4); +connection master1; +replace into tmp2_foo values (1), (2), (3), (4); + +connection master; +update tmp1_foo set a=2*a-1; +connection master1; +update tmp2_foo set a=2*a; + +connection master; +delete from tmp1_foo where a < 5; +connection master1; +delete from tmp2_foo where a < 5; + +connection master; +insert into foo select * from tmp1_foo; +connection master1; +insert into foo select * from tmp2_foo; + +connection master; +truncate table tmp1_foo; +connection master1; +truncate table tmp2_foo; + +flush logs; + +connection default; +select * from foo; + +# prepare for the replay +drop table foo; +create table foo (a int); + +# replay from binary log +exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000002 | $MYSQL; +select * from foo; + +# clean up +drop table foo; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b56e042e3d5..1a23077f6a0 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1010,6 +1010,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) share->db.str, share->table_name.str, 1)))) (void) rm_temporary_table(table_type, path); + else + thd->thread_specific_used= TRUE; + free_table_share(share); my_free((char*) table,MYF(0)); /* diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3ec03be72a5..4827810334f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4983,6 +4983,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, dst_path); /* purecov: inspected */ goto err; /* purecov: inspected */ } + thd->thread_specific_used= TRUE; } else if (err) {