Skip to content

Commit d762e9d

Browse files
committed
MDEV-32093 long uniques break old->new replication
recalculate long unique hash in Write_rows_log_event and Update_rows_log_event. normally generated columns (stored and indexed virtual) are deterministic and their values don't need to be recalculated on the slave as they're already present in the row image. but the long unique hash function was changed in MDEV-27653, so a row event from the old master will have the old hash, but a table created on the new slave will need a new hash.
1 parent c53cb71 commit d762e9d

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#
2+
# MDEV-22722 Assertion "inited==NONE" failed in handler::ha_index_init on the slave during UPDATE
3+
#
14
include/master-slave.inc
25
[connection master]
36
create table t1 (i1 int, a1 text, unique key i1 (a1)) engine=myisam;
@@ -6,7 +9,21 @@ insert into t1 values (2,2);
69
update t1 set a1 = 'd' limit 1;
710
update t1 set a1 = 'd2' where i1= 2;
811
connection slave;
9-
connection slave;
1012
connection master;
1113
drop table t1;
14+
#
15+
# MDEV-32093 long uniques break old->new replication
16+
#
17+
connection slave;
18+
create table t1 (id int not null, b1 varchar(255) not null, b2 varchar(2550) not null, unique (id), unique key (b1,b2) using hash) default charset utf8mb3;
19+
set global slave_exec_mode=idempotent;
20+
binlog 'aRf2ZA8BAAAA/AAAAAABAAAAAAQAMTAuNS4xNS1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpF/ZkEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFRmTlk';
21+
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
22+
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
23+
binlog 'bBf2ZBMBAAAANAAAAHUkAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AaTGFIg==bBf2ZBgBAAAASAAAAL0kAAAAAHEAAAAAAAEABP//8I+kAAABAGIBAGWuv1VNCQAAAPBuWwAAAQBiAQBlrr9VTQkAAADxS9Lu';
24+
drop table t1;
25+
set global slave_exec_mode=default;
26+
#
27+
# End of 10.4 tests
28+
#
1229
include/rpl_end.inc

mysql-test/main/long_unique_bugs_replication.test

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
# Long unique bugs related to master slave replication
33
#
44

5-
#
6-
# MDEV-22722 Assertion "inited==NONE" failed in handler::ha_index_init on the slave during UPDATE
7-
#
5+
--echo #
6+
--echo # MDEV-22722 Assertion "inited==NONE" failed in handler::ha_index_init on the slave during UPDATE
7+
--echo #
88

99
--source include/have_binlog_format_row.inc
1010
--source include/master-slave.inc
@@ -16,9 +16,34 @@ update t1 set a1 = 'd' limit 1;
1616
update t1 set a1 = 'd2' where i1= 2;
1717

1818
sync_slave_with_master;
19-
connection slave;
2019

2120
connection master;
2221
drop table t1;
2322

23+
--echo #
24+
--echo # MDEV-32093 long uniques break old->new replication
25+
--echo #
26+
27+
# this is techically a bug in replication, but it needs an old master
28+
# so we'll run it as a non-replicated test with BINLOG command
29+
sync_slave_with_master;
30+
create table t1 (id int not null, b1 varchar(255) not null, b2 varchar(2550) not null, unique (id), unique key (b1,b2) using hash) default charset utf8mb3;
31+
set global slave_exec_mode=idempotent;
32+
33+
# Format_description_log_event, MariaDB-10.5.15
34+
binlog 'aRf2ZA8BAAAA/AAAAAABAAAAAAQAMTAuNS4xNS1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpF/ZkEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFRmTlk';
35+
36+
### INSERT t1 VALUES (42127, 'b', 'e', 39952170926)
37+
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
38+
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
39+
40+
### UPDATE t1 WHERE (42127, 'b', 'e', 39952170926) SET (23406, 'b', 'e', 39952170926)
41+
binlog 'bBf2ZBMBAAAANAAAAHUkAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AaTGFIg==bBf2ZBgBAAAASAAAAL0kAAAAAHEAAAAAAAEABP//8I+kAAABAGIBAGWuv1VNCQAAAPBuWwAAAQBiAQBlrr9VTQkAAADxS9Lu';
42+
43+
drop table t1;
44+
set global slave_exec_mode=default;
45+
46+
--echo #
47+
--echo # End of 10.4 tests
48+
--echo #
2449
--source include/rpl_end.inc

sql/log_event.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13563,6 +13563,9 @@ Rows_log_event::write_row(rpl_group_info *rgi,
1356313563
DBUG_PRINT_BITSET("debug", "rpl_write_set: %s", table->rpl_write_set);
1356413564
DBUG_PRINT_BITSET("debug", "read_set: %s", table->read_set);
1356513565

13566+
if (table->s->long_unique_table)
13567+
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE);
13568+
1356613569
if (invoke_triggers &&
1356713570
unlikely(process_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE, TRUE)))
1356813571
{
@@ -13674,7 +13677,14 @@ Rows_log_event::write_row(rpl_group_info *rgi,
1367413677
Now, record[1] should contain the offending row. That
1367513678
will enable us to update it or, alternatively, delete it (so
1367613679
that we can insert the new row afterwards).
13677-
*/
13680+
*/
13681+
if (table->s->long_unique_table)
13682+
{
13683+
/* same as for REPLACE/ODKU */
13684+
table->move_fields(table->field, table->record[1], table->record[0]);
13685+
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE);
13686+
table->move_fields(table->field, table->record[0], table->record[1]);
13687+
}
1367813688

1367913689
/*
1368013690
If row is incomplete we will use the record found to fill
@@ -13684,6 +13694,8 @@ Rows_log_event::write_row(rpl_group_info *rgi,
1368413694
{
1368513695
restore_record(table,record[1]);
1368613696
error= unpack_current_row(rgi);
13697+
if (table->s->long_unique_table)
13698+
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE);
1368713699
}
1368813700

1368913701
DBUG_PRINT("debug",("preparing for update: before and after image"));
@@ -14791,6 +14803,8 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
1479114803
thd_proc_info(thd, message);
1479214804
if (unlikely((error= unpack_current_row(rgi, &m_cols_ai))))
1479314805
goto err;
14806+
if (m_table->s->long_unique_table)
14807+
m_table->update_virtual_fields(m_table->file, VCOL_UPDATE_FOR_WRITE);
1479414808

1479514809
/*
1479614810
Now we have the right row to update. The old row (the one we're

0 commit comments

Comments
 (0)