mirror of
https://github.com/MariaDB/server.git
synced 2025-08-31 22:22:30 +03:00
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for the size of the CHAR field. However, instead of denoting the number of characters in the field, field_length was used which denotes the number of bytes in the field. Since UTF-8 fields can have three bytes per character (and has been extended to have four bytes per character in 6.0), an extra two bits have been encoded in the field metadata work for fields of type Field_string (i.e., CHAR fields). Since the metadata word is filled, the extra bits have been encoded in the upper 4 bits of the real type (the most significant byte of the metadata word) by computing the bitwise xor of the extra two bits. Since the upper 4 bits of the real type always is 1111 for Field_string, this means that for fields of length <256, the encoding is identical to the encoding used in pre-5.1.26 servers, but for lengths of 256 or more, an unrecognized type is formed, causing an old slave (that does not handle lengths of 256 or more) to stop.
This commit is contained in:
@@ -437,7 +437,70 @@ SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
|
||||
COUNT(*) 0
|
||||
set @@global.slave_exec_mode= default;
|
||||
Last_SQL_Error
|
||||
0
|
||||
|
||||
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
|
||||
COUNT(*) 0
|
||||
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
|
||||
CREATE TABLE t1 (i INT NOT NULL,
|
||||
c CHAR(16) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
CREATE TABLE t2 (i INT NOT NULL,
|
||||
c CHAR(16) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
|
||||
CREATE TABLE t3 (i INT NOT NULL,
|
||||
c CHAR(128) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
|
||||
CREATE TABLE t4 (i INT NOT NULL,
|
||||
c CHAR(128) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
CREATE TABLE t5 (i INT NOT NULL,
|
||||
c CHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
|
||||
CREATE TABLE t6 (i INT NOT NULL,
|
||||
c CHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
|
||||
CREATE TABLE t7 (i INT NOT NULL,
|
||||
c CHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
j INT NOT NULL);
|
||||
[expecting slave to replicate correctly]
|
||||
INSERT INTO t1 VALUES (1, "", 1);
|
||||
INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
[expecting slave to replicate correctly]
|
||||
INSERT INTO t2 VALUES (1, "", 1);
|
||||
INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
|
||||
Comparing tables master:test.t2 and slave:test.t2
|
||||
[expecting slave to stop]
|
||||
INSERT INTO t3 VALUES (1, "", 1);
|
||||
INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
|
||||
Last_SQL_Error
|
||||
Table definition on master and slave does not match: Column 1 size mismatch - master has size 384, test.t3 on slave has size 49. Master's column size should be <= the slave's column size.
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=8;
|
||||
START SLAVE;
|
||||
[expecting slave to replicate correctly]
|
||||
INSERT INTO t4 VALUES (1, "", 1);
|
||||
INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
|
||||
Comparing tables master:test.t4 and slave:test.t4
|
||||
[expecting slave to stop]
|
||||
INSERT INTO t5 VALUES (1, "", 1);
|
||||
INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
|
||||
Last_SQL_Error
|
||||
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t5 on slave has size 49. Master's column size should be <= the slave's column size.
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=8;
|
||||
START SLAVE;
|
||||
[expecting slave to stop]
|
||||
INSERT INTO t6 VALUES (1, "", 1);
|
||||
INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
|
||||
Last_SQL_Error
|
||||
Table definition on master and slave does not match: Column 1 size mismatch - master has size 765, test.t6 on slave has size 385. Master's column size should be <= the slave's column size.
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=8;
|
||||
START SLAVE;
|
||||
[expecting slave to replicate correctly]
|
||||
INSERT INTO t7 VALUES (1, "", 1);
|
||||
INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
|
||||
Comparing tables master:test.t7 and slave:test.t7
|
||||
drop table t1, t2, t3, t4, t5, t6, t7;
|
||||
|
Reference in New Issue
Block a user