MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Luis Soares Date:March 3 2010 12:16pm
Subject:bzr commit into mysql-5.1-bugteam branch (luis.soares:3341) Bug#51226
View as plain text  
#At file:///home/lsoares/Workspace/bzr/work/bugfixing/51226/mysql-5.1-bugteam/ based on revid:joro@stripped

 3341 Luis Soares	2010-03-03
      BUG#51226: mysqlbinlog replay: ERROR 1146 when using temp tables
                 + failing statements
      
      Implicit DROP event for temporary table is not getting
      LOG_EVENT_THREAD_SPECIFIC_F flag, because, in the previous
      executed statement in the same thread, which might even be a
      failed statement, the thread_specific_used flag is set to
      FALSE (in mysql_reset_thd_for_next_command) and not set to TRUE
      before connection is shutdown. This means that implicit DROP
      event will take the FALSE value from thread_specific_used and
      will not set LOG_EVENT_THREAD_SPECIFIC_F in the event header. As
      a consequence, mysqlbinlog will not print the pseudo_thread_id
      from the DROP event, because one of the requirements for the
      printout is that this flag is set to TRUE.
      
      We fix this by setting thread_specific_used whenever we are
      binlogging a DROP in close_temporary_tables, and resetting it to
      its previous value afterward.

    modified:
      mysql-test/suite/binlog/r/binlog_tmp_table.result
      mysql-test/suite/binlog/t/binlog_tmp_table.test
      sql/sql_base.cc
=== modified file 'mysql-test/suite/binlog/r/binlog_tmp_table.result'
--- a/mysql-test/suite/binlog/r/binlog_tmp_table.result	2009-09-07 05:42:54 +0000
+++ b/mysql-test/suite/binlog/r/binlog_tmp_table.result	2010-03-03 12:16:18 +0000
@@ -29,3 +29,14 @@ a
 6
 8
 drop table foo;
+RESET MASTER;
+create database b51226;
+use b51226;
+create temporary table t1(i int);
+use b51226;
+create temporary table t1(i int);
+create temporary table t1(i int);
+ERROR 42S01: Table 't1' already exists
+insert into t1 values(1);
+DROP DATABASE b51226;
+FLUSH LOGS;

=== modified file 'mysql-test/suite/binlog/t/binlog_tmp_table.test'
--- a/mysql-test/suite/binlog/t/binlog_tmp_table.test	2009-09-07 05:42:54 +0000
+++ b/mysql-test/suite/binlog/t/binlog_tmp_table.test	2010-03-03 12:16:18 +0000
@@ -82,3 +82,69 @@ select * from foo;
 
 # clean up
 drop table foo;
+
+#################################################################
+# BUG#51226
+#################################################################
+
+RESET MASTER;
+
+-- let $dbname=b51226
+
+connect (con1,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
+connect (con2,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
+
+#
+# action: on con1 create the database and the tmp table
+# 
+-- connection con1
+-- eval create database $dbname
+-- eval use $dbname
+create temporary table t1(i int);
+
+#
+# action: on con1 create the tmp table
+# 
+-- connection con2
+-- eval use $dbname
+create temporary table t1(i int);
+
+# action: at this point, the last event binlogged contains the
+#         pseudo_thread_id from con2. So now we switch to con1, issue
+#         a statement that fails and close the connection (which logs
+#         implicitely a DROP TEMPORARY TABLE).  
+#
+#         Before the patch this would not log con1's pseudo_thread_id
+#         because the failing statement would reset THD context
+#         (unsetting the thread_specific_used flag, and consequently,
+#         causing the DROP event to be logged without pseudo_thread_id
+#         in its header).
+
+-- connection con1
+-- error 1050
+create temporary table t1(i int);
+-- disconnect con1
+
+-- connection default
+-- let $wait_binlog_event= DROP
+-- source include/wait_for_binlog_event.inc
+
+# action: insert in the t1. This would cause the the test to fail,
+#         because when replaying the binlog the previous implicit drop
+#         temp table would have been executed under the wrong
+#         pseudo_thread_id, dropping the tmp table on con2.
+-- connection con2
+insert into t1 values(1);
+-- disconnect con2
+
+-- connection default
+-- let $wait_binlog_event= DROP
+-- source include/wait_for_binlog_event.inc
+
+-- eval DROP DATABASE $dbname
+FLUSH LOGS;
+
+# assertion: assert that when replaying the binary log will succeed,
+#            instead of failing with "Table 'XXX.YYY' doesn't exist"
+-- let $MYSQLD_DATADIR= `select @@datadir`
+-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-01-27 13:10:53 +0000
+++ b/sql/sql_base.cc	2010-03-03 12:16:18 +0000
@@ -1515,6 +1515,7 @@ void close_temporary_tables(THD *thd)
   {
     if (is_user_table(table))
     {
+      bool save_thread_specific_used= thd->thread_specific_used;
       my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
       /* Set pseudo_thread_id to be that of the processed table */
       thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
@@ -1544,6 +1545,7 @@ void close_temporary_tables(THD *thd)
       thd->clear_error();
       CHARSET_INFO *cs_save= thd->variables.character_set_client;
       thd->variables.character_set_client= system_charset_info;
+      thd->thread_specific_used= TRUE;
       Query_log_event qinfo(thd, s_query.ptr(),
                             s_query.length() - 1 /* to remove trailing ',' */,
                             0, FALSE, 0);
@@ -1556,6 +1558,7 @@ void close_temporary_tables(THD *thd)
                      "Failed to write the DROP statement for temporary tables to binary log");
       }
       thd->variables.pseudo_thread_id= save_pseudo_thread_id;
+      thd->thread_specific_used= save_thread_specific_used;
     }
     else
     {


Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100303121618-rogb7p6xfvya0xf0.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (luis.soares:3341) Bug#51226Luis Soares3 Mar