List:Commits« Previous MessageNext Message »
From:Luis Soares Date:January 14 2010 11:01am
Subject:bzr commit into mysql-pe branch (luis.soares:3827) Bug#50018
View as plain text  
#At file:///home/lsoares/Workspace/bzr/work/bugfixing/50018/mysql-pe-push/ based on revid:joro@stripped

 3827 Luis Soares	2010-01-14 [merge]
      BUG#50018: automerge 5.1-bugteam latest --> mysql-pe latest.

    renamed:
      mysql-test/suite/binlog/r/binlog_tbl_metadata.result => mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result
      mysql-test/suite/binlog/t/binlog_tbl_metadata.test => mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
    modified:
      sql/log_event.cc
      mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result
      mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
=== renamed file 'mysql-test/suite/binlog/r/binlog_tbl_metadata.result' => 'mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result'
--- a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result	2009-05-12 11:53:46 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result	2010-01-07 17:45:54 +0000
@@ -1,5 +1,11 @@
-RESET MASTER;
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
 DROP TABLE IF EXISTS `t1`;
+### TABLE with field_metadata_size == 290
 CREATE TABLE `t1` (
 `c1` int(11) NOT NULL AUTO_INCREMENT,
 `c2` varchar(30) NOT NULL,
@@ -150,7 +156,51 @@ CREATE TABLE `t1` (
 PRIMARY KEY (`c1`)
 ) ENGINE=InnoDB;
 LOCK TABLES `t1` WRITE;
-INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1');
-DROP TABLE `t1`;
+INSERT INTO `t1`(c2) VALUES ('1');
 FLUSH LOGS;
+### assertion: the slave replicated event successfully and tables match
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE `t1`;
 === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail.
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+### action: generating several tables with different metadata 
+###         sizes (resorting to perl)
+### testing table with 249 field metadata size.
+### testing table with 250 field metadata size.
+### testing table with 251 field metadata size.
+### testing table with 252 field metadata size.
+### testing table with 253 field metadata size.
+### testing table with 254 field metadata size.
+### testing table with 255 field metadata size.
+### testing table with 256 field metadata size.
+### testing table with 257 field metadata size.
+### testing table with 258 field metadata size.
+FLUSH LOGS;
+### assertion: the slave replicated event successfully and tables match for t10
+Comparing tables master:test.t10 and slave:test.t10
+### assertion: the slave replicated event successfully and tables match for t9
+Comparing tables master:test.t9 and slave:test.t9
+### assertion: the slave replicated event successfully and tables match for t8
+Comparing tables master:test.t8 and slave:test.t8
+### assertion: the slave replicated event successfully and tables match for t7
+Comparing tables master:test.t7 and slave:test.t7
+### assertion: the slave replicated event successfully and tables match for t6
+Comparing tables master:test.t6 and slave:test.t6
+### assertion: the slave replicated event successfully and tables match for t5
+Comparing tables master:test.t5 and slave:test.t5
+### assertion: the slave replicated event successfully and tables match for t4
+Comparing tables master:test.t4 and slave:test.t4
+### assertion: the slave replicated event successfully and tables match for t3
+Comparing tables master:test.t3 and slave:test.t3
+### assertion: the slave replicated event successfully and tables match for t2
+Comparing tables master:test.t2 and slave:test.t2
+### assertion: the slave replicated event successfully and tables match for t1
+Comparing tables master:test.t1 and slave:test.t1
+### assertion: check that binlog is not corrupt. Using mysqlbinlog to 
+###            detect failure. Before the patch mysqlbinlog would find 
+###            a corrupted event, thence would fail.

=== renamed file 'mysql-test/suite/binlog/t/binlog_tbl_metadata.test' => 'mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test'
--- a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test	2009-05-12 11:53:46 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test	2010-01-14 10:49:40 +0000
@@ -2,38 +2,39 @@
 # BUG#42749: infinite loop writing to row based binlog - processlist shows
 # "freeing items"
 #
+#
 # WHY
 # ===
-#   
-#   This bug would make table map event to report data_written one byte less
-#   than what would actually be written in its body. This would cause one byte shorter
-#   event end_log_pos. The ultimate impact was that it would make fixing the
-#   position in MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop.
+#
+#   This bug would make table map event to report data_written one
+#   byte less than what would actually be written in its body. This
+#   would cause one byte shorter event end_log_pos. The ultimate
+#   impact was that it would make fixing the position in
+#   MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop.
 #
 # HOW
 # ===
 #
 #   Checking that the patch fixes the problem is done as follows:
-#     i) a table with several fields is created;
+#
+#     i) one table with m_field_metadata sized at 290
 #    ii) an insert is performed;
 #   iii) the logs are flushed;
 #    iv) mysqlbinlog is used to check if it succeeds.
 # 
-#   In step iv), before the bug was fixed, the test case would fail with
-#   mysqlbinlog reporting that it was unable to succeed in reading the event.
-#
+#   In step iv), before the bug was fixed, the test case would fail
+#   with mysqlbinlog reporting that it was unable to succeed in
+#   reading the event.
 
--- source include/have_log_bin.inc
+-- source include/master-slave.inc
 -- source include/have_innodb.inc
 -- source include/have_binlog_format_row.inc
--- connection default
-
-RESET MASTER;
 
 -- disable_warnings
 DROP TABLE IF EXISTS `t1`;
 -- enable_warnings
 
+-- echo ### TABLE with field_metadata_size == 290
 CREATE TABLE `t1` (
   `c1` int(11) NOT NULL AUTO_INCREMENT,
   `c2` varchar(30) NOT NULL,
@@ -185,15 +186,155 @@ CREATE TABLE `t1` (
 ) ENGINE=InnoDB;
 
 LOCK TABLES `t1` WRITE;
+INSERT INTO `t1`(c2) VALUES ('1');
+FLUSH LOGS;
+
+-- sync_slave_with_master
+-- connection master
 
-INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1');
+-- echo ### assertion: the slave replicated event successfully and tables match
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
 
 DROP TABLE `t1`;
 
-FLUSH LOGS;
+-- connection master
+-- sync_slave_with_master
+-- connection master
 
 -- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail.
 
 -- let $MYSQLD_DATADIR= `SELECT @@datadir`;
 -- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog
 -- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog
+
+#############################################################
+# BUG#50018: binlog corruption when table has many columns
+#
+# Same test from BUG#42749, but now we generate some SQL which
+# creates and inserts into tables with metadata size from 249
+# to 258.
+# 
+# The test works as follows:
+#  1. SQL for several CREATE TABLE and INSERTS are generated 
+#     into a file.
+#  2. This file is then "sourced"
+#  3. The slave is synchronized with the master
+#  4. FLUSH LOGS on master
+#  5. Compare tables on master and slave.
+#  6. run mysqlbinlog on  master's binary log
+#
+# Steps #5 and #6 assert that binary log is not corrupted 
+# in both cases: when slave is replaying events and when
+# mysqlbinlog is used to read the binary log
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+# Create several tables with field_metadata_size ranging
+# from 249 to 258 (so that we cover 251 and 255 range).
+# This should exercise the switch between using 1 or 3
+# bytes to pack m_field_metadata_size.
+# 
+# Each varchar field takes up to 2 metadata bytes, see:
+#
+#  Field_varstring::do_save_field_metadata (field.cc)
+#
+# The float field takes 1 byte, see:
+#
+#  Field_float::do_save_field_metadata (field.cc)
+#
+
+-- let $generated_sql= $MYSQLTEST_VARDIR/tmp/b50018.sql
+-- let B50018_FILE= $generated_sql
+
+-- echo ### action: generating several tables with different metadata 
+-- echo ###         sizes (resorting to perl)
+-- perl
+my $file= $ENV{'B50018_FILE'};
+open(FILE, ">", "$file") or die "Unable to open bug 50018 generated SQL file: $!" ;
+
+my $tables= "";
+my $ntables= 10;
+my $base_ncols= 124;
+
+for my $i (1..$ntables)
+{
+  my $ncols= $base_ncols + $i;
+  my $metadata_size= $ncols_variable * 2 + 1; 
+
+  print FILE "-- echo ### testing table with " . ($base_ncols*2 + $i) . " field metadata size.\n";
+  print FILE "CREATE TABLE t$i (\n";
+  for my $n (1..$base_ncols)
+  {
+    print FILE "c$n VARCHAR(30) NOT NULL DEFAULT 'BUG#50018',\n";
+  }
+
+  for my $n (1..$i)
+  {
+    print FILE "c" . ($base_ncols+$n) . " FLOAT NOT NULL DEFAULT 0";
+    if ($n < $i)
+    {
+      print FILE ",\n";
+    }
+  }
+
+  print FILE ") Engine=InnoDB;\n";
+
+  $tables.= " t$i WRITE";
+  if ($i < $ntables)
+  {
+    $tables .=",";
+  }
+    
+  print FILE "LOCK TABLES t$i WRITE;\n";
+  print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n";
+  print FILE "UNLOCK TABLES;";
+}
+
+close(FILE);
+
+EOF
+
+## we don't need this in the result file
+## however, for debugging purposes you 
+## may want to reactivate query logging
+-- disable_query_log 
+-- source $generated_sql
+-- enable_query_log
+
+-- sync_slave_with_master
+-- connection master
+
+FLUSH LOGS;
+
+-- let $ntables=10
+while($ntables)
+{
+  -- echo ### assertion: the slave replicated event successfully and tables match for t$ntables
+  -- let $diff_table_1=master:test.t$ntables
+  -- let $diff_table_2=slave:test.t$ntables
+  -- source include/diff_tables.inc
+
+  -- connection master
+  -- disable_query_log
+  -- eval DROP TABLE t$ntables
+  -- enable_query_log
+  -- sync_slave_with_master
+  -- connection master
+
+  -- dec $ntables
+}
+
+-- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to 
+-- echo ###            detect failure. Before the patch mysqlbinlog would find 
+-- echo ###            a corrupted event, thence would fail.
+-- let $MYSQLD_DATADIR= `SELECT @@datadir`;
+-- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog
+
+## clean up
+## For debugging purposes you might want not to remove these
+-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog
+-- remove_file $generated_sql
+-- source include/master-slave-end.inc

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-01-13 15:36:20 +0000
+++ b/sql/log_event.cc	2010-01-14 11:00:30 +0000
@@ -7979,10 +7979,10 @@ Table_map_log_event::Table_map_log_event
     plus one or three bytes (see pack.c:net_store_length) for number of 
     elements in the field metadata array.
   */
-  if (m_field_metadata_size > 255)
-    m_data_size+= m_field_metadata_size + 3; 
-  else
+  if (m_field_metadata_size < 251)
     m_data_size+= m_field_metadata_size + 1; 
+  else
+    m_data_size+= m_field_metadata_size + 3; 
 
   bzero(m_null_bits, num_null_bytes);
   for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)


Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100114110030-mdcio701qc0b2dqu.bundle
Thread
bzr commit into mysql-pe branch (luis.soares:3827) Bug#50018Luis Soares14 Jan