mirror of
https://github.com/MariaDB/server.git
synced 2025-08-28 21:31:39 +02:00

See also MDEV-30046. Idempotent write_row works same as REPLACE: if there is a duplicating record in the table, then it will be deleted and re-inserted, with the same update optimization. The code in Rows:log_event::write_row was basically copy-pasted from write_record. What's done: REPLACE operation was unified across replication and sql. It is now representred as a Write_record class, that holds the whole state, and allows re-using some resources in between the row writes. Replace, IODKU and single insert implementations are split across different methods, reluting in a much cleaner code. The entry point is preserved as a single Write_record::write_record() call. The implementation to call is chosen on the constructor stage. This allowed several optimizations to be done: 1. The table key list is not iterated for every row. We find last unique key in the order of checking once and preserve it across the rows. See last_uniq_key(). 2. ib_handler::referenced_by_foreign_key acquires a global lock. This call was done per row as well. Not all the table config that allows optimized replace is folded into a single boolean field can_optimize. All the fields to check are even stored in a single register on a 64-bit platform. 3. DUP_REPLACE and DUP_UPDATE cases now have one less level of indirection 4. modified_non_trans_tables is checked and set only when it's really needed. 5. Obsolete bitmap manipulations are removed. Also: * Unify replace initialization step across implementations: add prepare_for_replace and finalize_replace * alloca is removed in favor of mem_root allocation. This memory is reused across the rows. * An rpl-related callback is added to the replace branch, meaning that an extra check is made per row replace even for the common case. It can be avoided with templates if considered a problem.
73 lines
2.5 KiB
Text
73 lines
2.5 KiB
Text
#
|
|
# MDEV-22722 Assertion "inited==NONE" failed in handler::ha_index_init on the slave during UPDATE
|
|
#
|
|
include/master-slave.inc
|
|
[connection master]
|
|
create table t1 (i1 int, a1 text, unique key i1 (a1)) engine=myisam;
|
|
insert into t1 values (1,1);
|
|
insert into t1 values (2,2);
|
|
update t1 set a1 = 'd' limit 1;
|
|
update t1 set a1 = 'd2' where i1= 2;
|
|
connection slave;
|
|
connection slave;
|
|
select * from t1;
|
|
i1 a1
|
|
1 d
|
|
2 d2
|
|
connection master;
|
|
drop table t1;
|
|
connection slave;
|
|
connection master;
|
|
#
|
|
# MDEV-32093 long uniques break old->new replication
|
|
#
|
|
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;
|
|
set global slave_exec_mode=idempotent;
|
|
binlog 'aRf2ZA8BAAAA/AAAAAABAAAAAAQAMTAuNS4xNS1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpF/ZkEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFRmTlk';
|
|
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
|
|
binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw==';
|
|
binlog 'bBf2ZBMBAAAANAAAAHUkAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AaTGFIg==bBf2ZBgBAAAASAAAAL0kAAAAAHEAAAAAAAEABP//8I+kAAABAGIBAGWuv1VNCQAAAPBuWwAAAQBiAQBlrr9VTQkAAADxS9Lu';
|
|
connection slave;
|
|
select * from t1;
|
|
id b1 b2
|
|
23406 b e
|
|
connection master;
|
|
set global slave_exec_mode=default;
|
|
drop table t1;
|
|
#
|
|
# End of 10.4 tests
|
|
#
|
|
# Idempotent scenario, which triggers REPLACE code to be used in the
|
|
# event, i.e. duplicated record will be deleted and then re-inserted.
|
|
create table t1 (i1 int, a1 text, unique key i1 (a1)) engine=myisam;
|
|
connection slave;
|
|
connection slave;
|
|
set @save_slave_exec_mode= @@slave_exec_mode;
|
|
set global slave_exec_mode = idempotent;
|
|
insert into t1 values (1,1);
|
|
connection master;
|
|
insert into t1 values (2,1);
|
|
connection slave;
|
|
connection slave;
|
|
select * from t1;
|
|
i1 a1
|
|
2 1
|
|
connection master;
|
|
insert into t1 values (3,3);
|
|
update t1 set a1 = 'd' limit 1;
|
|
update t1 set a1 = 'd2' where i1= 3;
|
|
connection slave;
|
|
connection slave;
|
|
select * from t1;
|
|
i1 a1
|
|
2 d
|
|
3 d2
|
|
set global slave_exec_mode = @save_slave_exec_mode;
|
|
connection master;
|
|
drop table t1;
|
|
connection slave;
|
|
connection master;
|
|
#
|
|
# End of 10.4 tests
|
|
#
|
|
include/rpl_end.inc
|