From 754c8dab52a4dab33ebeb7f2fc79cd95b33bb9c2 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Tue, 19 Jul 2022 01:19:11 +0300 Subject: [PATCH] MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit ONLINE ALTER TABLE adds binlog handlerton into ha_list, so any rollback command can end up calling binlog_rollback having no cache_mngr, if binlog is not enabled. The assertion should be fixed in the same manner as DBUG_ASSERT(WSREP(thd)) --- .../main/alter_table_online_debug.result | 27 +++++++++++++ mysql-test/main/alter_table_online_debug.test | 39 +++++++++++++++++++ sql/log.cc | 6 ++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index 7c5fae54759..08a094db53a 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -952,5 +952,32 @@ alter table t1 force; drop table t1, t2; set debug_sync= reset; # +# MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit +# +create table t (a int) engine=innodb; +insert into t values (1); +xa begin 'xid'; +set debug_sync= 'now wait_for downgraded'; +connect con1,localhost,root,,test; +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit'; +alter table t force, algorithm=copy, lock=none; +connection default; +insert into t values (2); +set debug_sync= 'now signal goforit'; +xa end 'xid'; +xa rollback 'xid'; +xa begin 'xid'; +connection con1; +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit'; +alter table t force, algorithm=copy, lock=none; +connection default; +set debug_sync= 'now wait_for downgraded'; +insert into t values (3); +set debug_sync= 'now signal goforit'; +xa end 'xid'; +xa commit 'xid' one phase; +drop table t; +set debug_sync= reset; +# # End of 11.2 tests # diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index 9e0a47758c8..9d88c367a1d 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -1113,6 +1113,45 @@ alter table t1 force; drop table t1, t2; set debug_sync= reset; +--echo # +--echo # MDEV-29038 XA assertions failing in binlog_rollback and binlog_commit +--echo # +create table t (a int) engine=innodb; +insert into t values (1); +xa begin 'xid'; +--send +set debug_sync= 'now wait_for downgraded'; + +--connect (con1,localhost,root,,test) +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit'; +--send +alter table t force, algorithm=copy, lock=none; + +--connection default +--reap +insert into t values (2); +set debug_sync= 'now signal goforit'; +xa end 'xid'; +xa rollback 'xid'; + +xa begin 'xid'; +--connection con1 +--reap +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit'; +--send +alter table t force, algorithm=copy, lock=none; + +--connection default +set debug_sync= 'now wait_for downgraded'; +insert into t values (3); +set debug_sync= 'now signal goforit'; +xa end 'xid'; +xa commit 'xid' one phase; + +# Cleanup +drop table t; +set debug_sync= reset; + --echo # --echo # End of 11.2 tests --echo # diff --git a/sql/log.cc b/sql/log.cc index b65a730175a..f150235ee9d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2329,6 +2329,8 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc) PSI_stage_info org_stage; DBUG_ENTER("binlog_commit"); + IF_DBUG(bool commit_online= !thd->online_alter_cache_list.empty(),); + bool is_ending_transaction= ending_trans(thd, all); error= binlog_online_alter_end_trans(thd, all, true); if (error) @@ -2340,7 +2342,7 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc) */ if (!cache_mngr) { - DBUG_ASSERT(WSREP(thd) || + DBUG_ASSERT(WSREP(thd) || commit_online || (thd->lex->sql_command != SQLCOM_XA_PREPARE && !(thd->lex->sql_command == SQLCOM_XA_COMMIT && thd->lex->xa_opt == XA_ONE_PHASE))); @@ -2448,7 +2450,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) if (!cache_mngr) { DBUG_ASSERT(WSREP(thd) || rollback_online); - DBUG_ASSERT(thd->lex->sql_command != SQLCOM_XA_ROLLBACK); + DBUG_ASSERT(thd->lex->sql_command != SQLCOM_XA_ROLLBACK || rollback_online); DBUG_RETURN(0); }