List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:December 1 2010 9:47pm
Subject:bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3158) Bug#58147
View as plain text  
#At file:///Users/mattiasj/mysql-bzr/b58147-55-bt/ based on revid:nirbhay.choubey@stripped

 3158 Mattias Jonsson	2010-12-01
      Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails
                 but the statement is written to binlog
      
      TRUNCATE PARTITION was written to the binlog
      even if it failed before calling any partition's
      truncate function.
      
      Solved by adding an argument to truncate_partition,
      to flag if it should be written to the binlog or not.
      
      It should be written to the binlog when a call to any
      partitions truncate function is done.
     @ mysql-test/r/partition_binlog.result
        New result file
     @ mysql-test/t/partition_binlog.test
        New test file, including DROP PARTITION binlog test
     @ sql/ha_partition.cc
        Added argument to avoid binlogging failed truncate_partition that
        have not yet changed any data.
     @ sql/ha_partition.h
        Added argument to avoid excessive binlogging
     @ sql/sql_partition_admin.cc
        Avoid to binlog TRUNCATE PARTITION if it fails before
        any partition has tried to truncate.

    added:
      mysql-test/r/partition_binlog.result
      mysql-test/t/partition_binlog.test
    modified:
      sql/ha_partition.cc
      sql/ha_partition.h
      sql/sql_partition_admin.cc
=== added file 'mysql-test/r/partition_binlog.result'
--- a/mysql-test/r/partition_binlog.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/partition_binlog.result	2010-12-01 21:47:40 +0000
@@ -0,0 +1,56 @@
+DROP TABLE IF EXISTS t1;
+#
+# Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails
+#            but the statement is written to binlog
+#
+CREATE TABLE t1(id INT)
+PARTITION BY RANGE (id)
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION pmax VALUES LESS THAN (MAXVALUE));
+INSERT INTO t1 VALUES (1), (10), (100), (1000);
+ALTER TABLE t1 TRUNCATE PARTITION p1;
+ERROR HY000: Incorrect partition name
+ALTER TABLE t1 DROP PARTITION p1;
+ERROR HY000: Error in list of partitions to DROP
+# No error returned, output in table format instead:
+ALTER TABLE t1 ANALYZE PARTITION p1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	error	Error in list of partitions to test.t1
+ALTER TABLE t1 CHECK PARTITION p1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	error	Error in list of partitions to test.t1
+ALTER TABLE t1 OPTIMIZE PARTITION p1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	error	Error in list of partitions to test.t1
+ALTER TABLE t1 REPAIR PARTITION p1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	error	Error in list of partitions to test.t1
+ALTER TABLE t1 ANALYZE PARTITION p0;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	OK
+ALTER TABLE t1 CHECK PARTITION p0;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+ALTER TABLE t1 OPTIMIZE PARTITION p0;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+ALTER TABLE t1 REPAIR PARTITION p0;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+ALTER TABLE t1 TRUNCATE PARTITION p0;
+ALTER TABLE t1 DROP PARTITION p0;
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE t1(id INT)
+PARTITION BY RANGE (id)
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION pmax VALUES LESS THAN (MAXVALUE))
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (1), (10), (100), (1000)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	use `test`; ALTER TABLE t1 ANALYZE PARTITION p0
+master-bin.000001	#	Query	#	#	use `test`; ALTER TABLE t1 OPTIMIZE PARTITION p0
+master-bin.000001	#	Query	#	#	use `test`; ALTER TABLE t1 REPAIR PARTITION p0
+master-bin.000001	#	Query	#	#	use `test`; ALTER TABLE t1 TRUNCATE PARTITION p0
+master-bin.000001	#	Query	#	#	use `test`; ALTER TABLE t1 DROP PARTITION p0
+DROP TABLE t1;

=== added file 'mysql-test/t/partition_binlog.test'
--- a/mysql-test/t/partition_binlog.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_binlog.test	2010-12-01 21:47:40 +0000
@@ -0,0 +1,42 @@
+--source include/have_log_bin.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # Bug#58147: ALTER TABLE w/ TRUNCATE PARTITION fails
+--echo #            but the statement is written to binlog
+--echo #
+
+--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1)
+--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1)
+
+CREATE TABLE t1(id INT)
+PARTITION BY RANGE (id)
+(PARTITION p0 VALUES LESS THAN (100),
+ PARTITION pmax VALUES LESS THAN (MAXVALUE));
+
+INSERT INTO t1 VALUES (1), (10), (100), (1000);
+
+--error ER_WRONG_PARTITION_NAME
+ALTER TABLE t1 TRUNCATE PARTITION p1;
+--error ER_DROP_PARTITION_NON_EXISTENT
+ALTER TABLE t1 DROP PARTITION p1;
+
+--echo # No error returned, output in table format instead:
+ALTER TABLE t1 ANALYZE PARTITION p1;
+ALTER TABLE t1 CHECK PARTITION p1;
+ALTER TABLE t1 OPTIMIZE PARTITION p1;
+ALTER TABLE t1 REPAIR PARTITION p1;
+
+ALTER TABLE t1 ANALYZE PARTITION p0;
+ALTER TABLE t1 CHECK PARTITION p0;
+ALTER TABLE t1 OPTIMIZE PARTITION p0;
+ALTER TABLE t1 REPAIR PARTITION p0;
+ALTER TABLE t1 TRUNCATE PARTITION p0;
+ALTER TABLE t1 DROP PARTITION p0;
+
+--source include/show_binlog_events.inc
+
+DROP TABLE t1;

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2010-11-26 14:32:51 +0000
+++ b/sql/ha_partition.cc	2010-12-01 21:47:40 +0000
@@ -3428,7 +3428,7 @@ int ha_partition::truncate()
   ALTER TABLE t TRUNCATE PARTITION ...
 */
 
-int ha_partition::truncate_partition(Alter_info *alter_info)
+int ha_partition::truncate_partition(Alter_info *alter_info, bool *to_binlog)
 {
   int error= 0;
   List_iterator<partition_element> part_it(m_part_info->partitions);
@@ -3440,6 +3440,9 @@ int ha_partition::truncate_partition(Alt
                                         PART_ADMIN);
   DBUG_ENTER("ha_partition::truncate_partition");
 
+  /* Only binlog when it starts any call to the partitions handlers */
+  *to_binlog= false;
+
   /*
     TRUNCATE also means resetting auto_increment. Hence, reset
     it so that it will be initialized again at the next use.
@@ -3453,6 +3456,8 @@ int ha_partition::truncate_partition(Alt
       (!(alter_info->flags & ALTER_ALL_PARTITION)))
     DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
 
+  *to_binlog= true;
+
   do
   {
     partition_element *part_elem= part_it++;

=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h	2010-10-28 10:08:09 +0000
+++ b/sql/ha_partition.h	2010-12-01 21:47:40 +0000
@@ -362,7 +362,7 @@ public:
     @remark This method is a partitioning-specific hook
             and thus not a member of the general SE API.
   */
-  int truncate_partition(Alter_info *);
+  int truncate_partition(Alter_info *, bool *to_binlog);
 
   virtual bool is_fatal_error(int error, uint flags)
   {

=== modified file 'sql/sql_partition_admin.cc'
--- a/sql/sql_partition_admin.cc	2010-10-28 10:08:09 +0000
+++ b/sql/sql_partition_admin.cc	2010-12-01 21:47:40 +0000
@@ -110,6 +110,7 @@ bool Alter_table_truncate_partition_stat
   ha_partition *partition;
   ulong timeout= thd->variables.lock_wait_timeout;
   TABLE_LIST *first_table= thd->lex->select_lex.table_list.first;
+  bool to_binlog;
   DBUG_ENTER("Alter_table_truncate_partition_statement::execute");
 
   /*
@@ -161,16 +162,18 @@ bool Alter_table_truncate_partition_stat
   partition= (ha_partition *) first_table->table->file;
 
   /* Invoke the handler method responsible for truncating the partition. */
-  if ((error= partition->truncate_partition(&thd->lex->alter_info)))
+  if ((error= partition->truncate_partition(&thd->lex->alter_info,
+                                            &to_binlog)))
     first_table->table->file->print_error(error, MYF(0));
 
   /*
     All effects of a truncate operation are committed even if the
     operation fails. Thus, the query must be written to the binary
-    log. The only exception is a unimplemented truncate method. Also,
-    it is logged in statement format, regardless of the binlog format.
+    log. The exception is a unimplemented truncate method or failure
+    before any call to handler::truncate() is done.
+    Also, it is logged in statement format, regardless of the binlog format.
   */
-  if (error != HA_ERR_WRONG_COMMAND)
+  if (error != HA_ERR_WRONG_COMMAND && to_binlog)
     error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
 
   /*


Attachment: [text/bzr-bundle] bzr/mattias.jonsson@oracle.com-20101201214740-tm04k86gphndg02x.bundle
Thread
bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3158) Bug#58147Mattias Jonsson1 Dec
  • Re: bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3158)Bug#58147Davi Arnaut1 Dec