#At file:///home/lsoares/Workspace/bzr/work/bugfixing/53386/mysql-trunk-bugfixing/ based on revid:alfranio.correia@oracle.com-20101010223253-ch7qfomlmpk0r6ct
3288 Luis Soares 2010-10-29
BUG#53386: HA_ERR_CORRUPT_EVENT or debug assertion with different
table on slave
When the number of raw bytes used for a CHAR field exceeds 255
two bytes are actually used while packing the length of the
field. CHAR fields can exceed the raw 255 byte length, for
instance, if using multi-byte character sets.
The problem is that when calculating the raw length of the field,
at unpacking time, only one byte was assumed to be used
always. Therefore, the number of bytes used would not add up,
triggering the assertion.
We fix this, by making the member function that calculates the
raw byte length for a given field to take into account the actual
number of bytes used while packing the field length.
@ mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test
Extended the test case with one based on the bug report entry.
@ sql/rpl_record.cc
Added assertion so that calc_field_size always matches the
size returned by field->unpack.
@ sql/rpl_utility.cc
Changed calc_field_size so that either one or two bytes are
taken into account, depending on the maximum field size.
Additionally, fixed one wrong assertion that had been
deployed when calculating the field size of a varchar type.
modified:
mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test
mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result
mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result
sql/rpl_record.cc
sql/rpl_utility.cc
=== modified file 'mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test'
--- a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test 2010-06-22 09:34:59 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test 2010-10-29 12:43:28 +0000
@@ -1029,4 +1029,38 @@ sync_slave_with_master;
# END of 5.1 tests case
+#
+# BUG#53386: HA_ERR_CORRUPT_EVENT or debug assertion with different table on slave
+#
+
+-- connection master
+-- source include/master-slave-reset.inc
+-- connection master
+
+# CREATE Different tables on master and slave
+SET SQL_LOG_BIN=0;
+-- eval CREATE TABLE t1 (c1 INT NOT NULL, c2 CHAR(255) CHARACTER SET UTF8 NOT NULL) ENGINE=$engine_type
+SET SQL_LOG_BIN=1;
+-- connection slave
+-- eval CREATE TABLE t1 (c1 INT) ENGINE=$engine_type
+
+# insert empty row (c2 gets an empty string)
+-- connection master
+
+-- disable_warnings
+INSERT INTO t1 VALUES ();
+
+# insert multi-byte chars that will take more than 255 bytes
+SET @text= REPEAT('ç', 255);
+INSERT INTO t1 VALUES (1, @text);
+-- enable_warnings
+
+SELECT * FROM t1;
+-- sync_slave_with_master
+SELECT * FROM t1;
+
+# clean up
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
=== modified file 'mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result 2010-06-22 09:34:59 +0000
+++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result 2010-10-29 12:43:28 +0000
@@ -876,3 +876,25 @@ c1 hex(c4) c5
3 6231623162316231 QA
DROP TABLE t5;
+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;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (c1 INT NOT NULL, c2 CHAR(255) CHARACTER SET UTF8 NOT NULL) ENGINE='InnoDB';
+SET SQL_LOG_BIN=1;
+CREATE TABLE t1 (c1 INT) ENGINE='InnoDB';
+INSERT INTO t1 VALUES ();
+SET @text= REPEAT('ç', 255);
+INSERT INTO t1 VALUES (1, @text);
+SELECT * FROM t1;
+c1 c2
+0
+1 çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççc1
+0
+1
+DROP TABLE t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result 2010-06-22 09:34:59 +0000
+++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result 2010-10-29 12:43:28 +0000
@@ -876,3 +876,25 @@ c1 hex(c4) c5
3 6231623162316231 QA
DROP TABLE t5;
+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;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (c1 INT NOT NULL, c2 CHAR(255) CHARACTER SET UTF8 NOT NULL) ENGINE='MyISAM';
+SET SQL_LOG_BIN=1;
+CREATE TABLE t1 (c1 INT) ENGINE='MyISAM';
+INSERT INTO t1 VALUES ();
+SET @text= REPEAT('ç', 255);
+INSERT INTO t1 VALUES (1, @text);
+SELECT * FROM t1;
+c1 c2
+0
+1 çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççOM t1;
+c1
+0
+1
+DROP TABLE t1;
=== modified file 'sql/rpl_record.cc'
--- a/sql/rpl_record.cc 2010-07-24 13:47:42 +0000
+++ b/sql/rpl_record.cc 2010-10-29 12:43:28 +0000
@@ -324,6 +324,13 @@ unpack_row(Relay_log_info const *rli,
f->field_name, metadata,
(ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
+
+ /*
+ The raw size of the field, as calculated in calc_field_size,
+ should match the one reported by Field_*::unpack.
+ */
+ DBUG_ASSERT(tabledef->calc_field_size(i, (uchar *) old_pack_ptr) ==
+ (pack_ptr - old_pack_ptr));
}
/*
=== modified file 'sql/rpl_utility.cc'
--- a/sql/rpl_utility.cc 2010-07-16 21:00:50 +0000
+++ b/sql/rpl_utility.cc 2010-10-29 12:43:28 +0000
@@ -225,10 +225,12 @@ uint32 table_def::calc_field_size(uint c
/*
We are reading the actual size from the master_data record
because this field has the actual lengh stored in the first
- byte.
+ one or two bytes.
*/
- length= (uint) *master_data + 1;
- DBUG_ASSERT(length != 0);
+ length= max_display_length_for_field(MYSQL_TYPE_STRING, m_field_metadata[col]) > 255 ? 2 : 1;
+
+ /* As in Field_string::unpack */
+ length+= ((length == 1) ? *master_data : uint2korr(master_data));
}
break;
}
@@ -284,7 +286,6 @@ uint32 table_def::calc_field_size(uint c
case MYSQL_TYPE_VARCHAR:
{
length= m_field_metadata[col] > 255 ? 2 : 1; // c&p of Field_varstring::data_length()
- DBUG_ASSERT(uint2korr(master_data) > 0);
length+= length == 1 ? (uint32) *master_data : uint2korr(master_data);
break;
}
Attachment: [text/bzr-bundle] bzr/luis.soares@oracle.com-20101029124328-rx2i88s91y3vwgpj.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-bugfixing branch (luis.soares:3288) Bug#53386 | Luis Soares | 29 Oct |