commit 927d18ab113d663db0f622c5b78b8f2936c89714 Author: Dmitry Lenev Date: Wed Nov 8 09:40:29 2023 +0100 Bug #113002: innodb.ddl_kill test fails sporadically. Sporadical failures of innodb.ddl_kill test were caused by two factors: 1) Sometimes parallel ALTER TABLE ADD INDEX implementation executed its BTREE_BUILD step not in thread of connection which got ALTER TABLE, but in one of auxiliary worker threads. In this case 'ddl_btree_build_interrupt' debug sync point placed at the start of this step and used by the test case was ignored. The problem was that DEBUG_SYNC_C_IF_THD() macro, which were used to set this sync point, even though gets THD as its first argument still, also, relies on 'current_thd' thread-local variable being set to non-0 value, which was not the case for auxiliary worker threads. 2) The first part of the test case didn't reset properly state of debug sync point facility after ALTER TABLE statement waiting on sync point was killed. This resulted in non-empty set of debug signals set when we entered second part of the test, breaking its logic. This patch solves the former issue by replacing DEBUG_SYNC_C_IF_THD() macro usage by BTREE_BUILD step with simple DEBUG_SYNC() call. This macro provides equivalent functionality in this specific case, while not relying on current_thd value. The latter issue is addressed by resetting state of debug sync facility after execution of the first part of the test case. diff --git a/mysql-test/suite/innodb/r/ddl_kill.result b/mysql-test/suite/innodb/r/ddl_kill.result index 8ff7e99c57a..11ee739782c 100644 --- a/mysql-test/suite/innodb/r/ddl_kill.result +++ b/mysql-test/suite/innodb/r/ddl_kill.result @@ -20,6 +20,9 @@ KILL QUERY @id; SET DEBUG_SYNC='now SIGNAL interrupt'; # con1: reap ERROR 70100: Query execution was interrupted +# Cleanup. Since ALTER TABLE was killed while waiting on sync point +# 'interrupt' signal might have been not received and properly cleared. +SET DEBUG_SYNC='RESET'; # con2: Start the DDL SET SESSION DEBUG='+d,ddl_btree_build_interrupt'; SET DEBUG_SYNC='ddl_btree_build_interrupt SIGNAL ready WAIT_FOR interrupt'; diff --git a/mysql-test/suite/innodb/t/ddl_kill.test b/mysql-test/suite/innodb/t/ddl_kill.test index 464c2492e3a..3cc14e01f95 100644 --- a/mysql-test/suite/innodb/t/ddl_kill.test +++ b/mysql-test/suite/innodb/t/ddl_kill.test @@ -39,6 +39,10 @@ connection con1; --error ER_QUERY_INTERRUPTED --reap +--echo # Cleanup. Since ALTER TABLE was killed while waiting on sync point +--echo # 'interrupt' signal might have been not received and properly cleared. +SET DEBUG_SYNC='RESET'; + connect (con2,localhost,root,,); connection con2; --echo # con2: Start the DDL diff --git a/storage/innobase/ddl/ddl0builder.cc b/storage/innobase/ddl/ddl0builder.cc index 27d59382c4b..2b408e2be71 100644 --- a/storage/innobase/ddl/ddl0builder.cc +++ b/storage/innobase/ddl/ddl0builder.cc @@ -1715,7 +1715,7 @@ dberr_t Builder::check_duplicates(Thread_ctxs &dupcheck, Dup *dup) noexcept { dberr_t Builder::btree_build() noexcept { ut_a(!is_skip_file_sort()); - DEBUG_SYNC_C_IF_THD(m_ctx.thd(), "ddl_btree_build_interrupt"); + DEBUG_SYNC(m_ctx.thd(), "ddl_btree_build_interrupt"); if (m_local_stage != nullptr) { m_local_stage->begin_phase_insert(); }