1
0
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:
Nikita Malyavin
2023-09-19 18:19:10 +04:00
parent a1019e93d6
commit 830bdfccbd
6 changed files with 172 additions and 17 deletions

View File

@ -1518,6 +1518,51 @@ connection default;
drop table t1;
set debug_sync= reset;
drop table iso_levels;
# 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';
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');
insert into t2 values (3,3,'a','x'), (3,3,'a','x');
ERROR 23000: Duplicate entry '3' for key 'a'
insert into t2 values (3,3,'a','x');
commit;
set debug_sync= 'now signal go_alter';
connection default;
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';
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;
insert into t2 values (3,3,'a','x'), (3,3,'a','x');
ERROR 23000: Duplicate entry '3' for key 'a'
insert into t2 values (3,3,'a','x');
commit;
set debug_sync= 'now signal go_alter';
connection default;
drop table t1, t2;
set @@binlog_format=default;
set debug_sync= reset;
disconnect con1;
disconnect con2;
#