mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-32126 Assertion fails upon online ALTER and binary log enabled
Assertion `!writer.checksum_len || writer.remains == 0' fails upon concurrent online ALTER and transactions with failing statements and binary log enabled. Also another assertion, `pos != (~(my_off_t) 0)', fails in my_seek, upon reinit_io_cache, on a simplified test. This means that IO_CACHE wasn't properly initialized, or had an error before. The overall problem is a deep interference with the effect of an installed binlog_hton: the assumption about that thd->binlog_get_cache_mngr() is, sufficiently, NULL, when we shouldn't run the binlog part of binlog_commit/binlog_rollback, is wrong: as turns out, sometimes the binlog handlerton can be not installed in current thd, but binlog_commit can be called on behalf of binlog, as in the bug reported. One separate condition found is XA recovery of the orphaned transaction, when binlog_commit is also called, but it has nothing to do with online alter. Solution: Extract online alter operations into a separate handlerton.
This commit is contained in:
@ -1736,6 +1736,60 @@ set debug_sync= reset;
|
||||
drop table iso_levels;
|
||||
|
||||
|
||||
--echo # MDEV-32126 Assertion fails upon online ALTER and binary log enabled
|
||||
create temporary table tmp (id int, primary key(id)) engine=innodb;
|
||||
create table t1 (a int, b text) engine=innodb;
|
||||
create table t2 (a int, b int, c char(8), d text, unique(a)) engine=innodb;
|
||||
insert into t2 values (1,1,'f','e'),(1000,1000,'c','b');
|
||||
--connection default
|
||||
set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter';
|
||||
send alter table t2 force, algorithm=copy, lock=none;
|
||||
|
||||
--connection con2
|
||||
set debug_sync= 'now wait_for go_trx';
|
||||
start transaction;
|
||||
insert into t1 values (3,'a');
|
||||
--error ER_DUP_ENTRY
|
||||
insert into t2 values (3,3,'a','x'), (3,3,'a','x');
|
||||
insert into t2 values (3,3,'a','x');
|
||||
commit;
|
||||
set debug_sync= 'now signal go_alter';
|
||||
--connection default
|
||||
--reap
|
||||
truncate t2;
|
||||
set @@binlog_format=mixed;
|
||||
--connection con2
|
||||
start transaction;
|
||||
create temporary table tmp (id int, primary key(id)) engine=innodb;
|
||||
insert into t1 values (1, repeat('x',8000)),(2, repeat('x',8000));
|
||||
update t2 set b = null order by b limit 2;
|
||||
insert into t1 values (3, repeat('x',8000));
|
||||
delete from t1;
|
||||
insert into t2 values (1,1,'f','e'),(1000,1000,'c','b');
|
||||
commit;
|
||||
|
||||
|
||||
--connection default
|
||||
set debug_sync= 'alter_table_online_before_lock signal go_trx wait_for go_alter';
|
||||
send alter table t2 force, algorithm=copy, lock=none;
|
||||
|
||||
--connection con2
|
||||
set debug_sync= 'now wait_for go_trx';
|
||||
start transaction;
|
||||
drop temporary table if exists tmp;
|
||||
--error ER_DUP_ENTRY
|
||||
insert into t2 values (3,3,'a','x'), (3,3,'a','x');
|
||||
insert into t2 values (3,3,'a','x');
|
||||
commit;
|
||||
set debug_sync= 'now signal go_alter';
|
||||
|
||||
--connection default
|
||||
--reap
|
||||
|
||||
drop table t1, t2;
|
||||
set @@binlog_format=default;
|
||||
set debug_sync= reset;
|
||||
|
||||
|
||||
--disconnect con1
|
||||
--disconnect con2
|
||||
|
Reference in New Issue
Block a user