mirror of
https://github.com/MariaDB/server.git
synced 2025-07-05 12:42:17 +03:00
The slave was not able to find the correct row in the innodb table, because the row fetched from the innodb table would not match the before image. This happened because the (don't care) bytes in the NULLed fields would change once the row was stored in the storage engine (from zero to the default value). This would make bulk memory comparison (using memcmp) to fail. We fix this by taking a preventing measure and avoiding memcmp for tables that contain nullable fields. Therefore, we protect the slave search routine from engines that return arbitrary values for don't care bytes (in the nulled fields). Instead, the slave thread will only check null_bits and those fields that are not set to NULL when comparing the before image against the storage engine row. mysql-test/extra/rpl_tests/rpl_record_compare.test: Added test case to the include file so that this is tested with more than one engine. mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result: Result update. mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result: Result update. mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test: Moved the include file last, so that the result from BUG#11766865 is not intermixed with the result for BUG#11760454. sql/log_event.cc: Skips memory comparison if the table has nullable columns and compares only non-nulled fields in the field comparison loop.
35 lines
1.7 KiB
Plaintext
35 lines
1.7 KiB
Plaintext
include/master-slave.inc
|
|
[connection master]
|
|
## case #1 - last_null_bit_pos==0 in record_compare without X bit
|
|
include/rpl_reset.inc
|
|
CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
|
|
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
|
|
UPDATE t1 SET c5 = 'a';
|
|
include/diff_tables.inc [master:t1, slave:t1]
|
|
DROP TABLE t1;
|
|
## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
|
|
## (1 column less and no varchar)
|
|
include/rpl_reset.inc
|
|
CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
|
|
INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
|
|
UPDATE t1 SET c5 = 'a';
|
|
include/diff_tables.inc [master:t1, slave:t1]
|
|
DROP TABLE t1;
|
|
## case #2 - X bit is wrongly set.
|
|
include/rpl_reset.inc
|
|
CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=InnoDB DEFAULT CHARSET= latin1;
|
|
INSERT INTO t1(c1) VALUES (10);
|
|
INSERT INTO t1(c1) VALUES (NULL);
|
|
UPDATE t1 SET c1= 0;
|
|
include/diff_tables.inc [master:t1, slave:t1]
|
|
DROP TABLE t1;
|
|
include/rpl_reset.inc
|
|
CREATE TABLE t1 (c1 int(11) NOT NULL, c2 int(11) NOT NULL, c3 int(11) DEFAULT '-1') ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
INSERT INTO t1 VALUES (1,2,NULL);
|
|
UPDATE t1 SET c1=1, c2=2, c3=-1 WHERE c1=1 AND c2=2 AND ISNULL(c3);
|
|
include/diff_tables.inc [master:test.t1, slave:test.t1]
|
|
DROP TABLE t1;
|
|
include/rpl_end.inc
|