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

 3341 Luis Soares	2010-02-19
      BUG#51251: Wrong binlogging in case of TRUNCATE <temporary InnoDB table>
      
      For temporary tables that are created with an engine that does
      not provide the HTON_CAN_RECREATE, the truncate operation is
      performed resorting to the optimized handler::ha_delete_all_rows
      method. However, this means that the truncate will share
      execution path, from mysql_delete, with truncate on regular
      tables and other delete operations. As a consequence the truncate
      operation, for the temporary table is logged, even if in row mode
      because there is no distinction between this and the other delete
      operations at binlogging time.
      
      We fix this by checking if: (i) the binlog format, when the
      truncate operation was issued, is ROW; (ii) if the operation is a
      truncate; and (iii) if the table is a temporary table; before
      writing to the binary log. If all three conditions are met, we
      skip writing to the binlog.
     @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
        Updated result for spurious truncate table.
     @ mysql-test/suite/binlog/t/binlog_row_innodb_truncate.test
        Test case.
     @ sql/mysql_priv.h
        Added parameter in mysql_delete interface.
     @ sql/sql_delete.cc
        Added check in mysql_delete before writing the TRUNCATE statement
        to the binary log.
     @ sql/sql_parse.cc
        Added value for the new parameter in mysql_delete.

    added:
      mysql-test/suite/binlog/r/binlog_row_innodb_truncate.result
      mysql-test/suite/binlog/t/binlog_row_innodb_truncate.test
    modified:
      mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
      sql/mysql_priv.h
      sql/sql_delete.cc
      sql/sql_parse.cc
=== added file 'mysql-test/suite/binlog/r/binlog_row_innodb_truncate.result'
--- a/mysql-test/suite/binlog/r/binlog_row_innodb_truncate.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_innodb_truncate.result	2010-02-19 00:22:18 +0000
@@ -0,0 +1,28 @@
+CREATE TABLE t1 ( c1 int , primary key (c1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE TEMPORARY TABLE IF NOT EXISTS  t2 LIKE t1;
+TRUNCATE TABLE t2;
+DROP TABLE t1;
+###############################################
+### assertion: No event for 'TRUNCATE TABLE t2'
+###############################################
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE t1 ( c1 int , primary key (c1)) ENGINE=InnoDB
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `test`; DROP TABLE t1
+###############################################
+RESET MASTER;
+CREATE TEMPORARY TABLE t1 (c1 int) Engine=InnoDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+TRUNCATE t1;
+DROP TEMPORARY TABLE t1;
+###############################################
+### assertion: No event for 'TRUNCATE TABLE t1'
+###############################################
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+###############################################

=== modified file 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result	2010-01-22 09:38:21 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result	2010-02-19 00:22:18 +0000
@@ -413,7 +413,6 @@ master-bin.000001	#	Query	#	#	BEGIN
 master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
 master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	COMMIT
-master-bin.000001	#	Query	#	#	use `test`; TRUNCATE table t2
 master-bin.000001	#	Query	#	#	BEGIN
 master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
 master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F

=== added file 'mysql-test/suite/binlog/t/binlog_row_innodb_truncate.test'
--- a/mysql-test/suite/binlog/t/binlog_row_innodb_truncate.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_row_innodb_truncate.test	2010-02-19 00:22:18 +0000
@@ -0,0 +1,37 @@
+-- source include/have_binlog_format_row.inc
+-- source include/have_innodb.inc
+
+#
+# BUG#51251
+#
+# The test case checks if truncating a temporary table created with
+# engine InnoDB will not cause the truncate statement to be binlogged.
+
+# Before patch for BUG#51251, the TRUNCATE statements below would be
+# binlogged, which would cause the slave to fail with "table does not
+# exist".
+
+CREATE TABLE t1 ( c1 int , primary key (c1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE TEMPORARY TABLE IF NOT EXISTS  t2 LIKE t1;
+TRUNCATE TABLE t2;
+DROP TABLE t1;
+
+-- echo ###############################################
+-- echo ### assertion: No event for 'TRUNCATE TABLE t2'
+-- echo ###############################################
+-- source include/show_binlog_events.inc
+-- echo ###############################################
+
+RESET MASTER;
+
+CREATE TEMPORARY TABLE t1 (c1 int) Engine=InnoDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+TRUNCATE t1;
+DROP TEMPORARY TABLE t1;
+
+-- echo ###############################################
+-- echo ### assertion: No event for 'TRUNCATE TABLE t1'
+-- echo ###############################################
+-- source include/show_binlog_events.inc
+-- echo ###############################################

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2010-02-09 10:30:50 +0000
+++ b/sql/mysql_priv.h	2010-02-19 00:22:18 +0000
@@ -1277,7 +1277,7 @@ void prepare_triggers_for_insert_stmt(TA
 int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
 bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
                   SQL_LIST *order, ha_rows rows, ulonglong options,
-                  bool reset_auto_increment);
+                  bool reset_auto_increment, bool saved_binlog_format_row);
 bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok);
 bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create);
 uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2010-01-24 07:03:23 +0000
+++ b/sql/sql_delete.cc	2010-02-19 00:22:18 +0000
@@ -34,7 +34,7 @@
 
 bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
                   SQL_LIST *order, ha_rows limit, ulonglong options,
-                  bool reset_auto_increment)
+                  bool reset_auto_increment, bool save_binlog_row_based)
 {
   bool          will_batch;
   int		error, loc_error;
@@ -390,7 +390,10 @@ cleanup:
   /* See similar binlogging code in sql_update.cc, for comments */
   if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
   {
-    if (mysql_bin_log.is_open())
+    if (mysql_bin_log.is_open() &&
+        !(thd->lex->sql_command == SQLCOM_TRUNCATE &&
+          save_binlog_row_based &&
+          find_temporary_table(thd, table_list)))
     {
       bool const is_trans=
         thd->lex->sql_command == SQLCOM_TRUNCATE ?
@@ -1064,7 +1067,7 @@ static bool mysql_truncate_by_delete(THD
   table_list->lock_type= TL_WRITE;
   mysql_init_select(thd->lex);
   thd->clear_current_stmt_binlog_row_based();
-  error= mysql_delete(thd, table_list, NULL, NULL, HA_POS_ERROR, LL(0), TRUE);
+  error= mysql_delete(thd, table_list, NULL, NULL, HA_POS_ERROR, LL(0), TRUE, save_binlog_row_based);
   ha_autocommit_or_rollback(thd, error);
   end_trans(thd, error ? ROLLBACK : COMMIT);
   thd->current_stmt_binlog_row_based= save_binlog_row_based;

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-02-05 17:01:09 +0000
+++ b/sql/sql_parse.cc	2010-02-19 00:22:18 +0000
@@ -3309,7 +3309,7 @@ end_with_restore_list:
     res = mysql_delete(thd, all_tables, select_lex->where,
                        &select_lex->order_list,
                        unit->select_limit_cnt, select_lex->options,
-                       FALSE);
+                       FALSE, thd->current_stmt_binlog_row_based);
     break;
   }
   case SQLCOM_DELETE_MULTI:


Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100219002218-g5o5uz2jgw1qcxmn.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (luis.soares:3341) Bug#51251Luis Soares19 Feb
  • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:3341)Bug#51251Alfranio Correia22 Feb
    • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:3341)Bug#51251Luís Soares22 Feb
      • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:3341)Bug#51251Luís Soares9 Mar
        • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:3341)Bug#51251Luís Soares10 Mar
Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:3341)Bug#51251Luís Soares24 Feb