From b68c100076ceed77e0260e2906f0944d5f696503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 20 Aug 2024 18:00:23 +0300 Subject: [PATCH 01/10] MDEV-34565 MariaDB crashes with SIGILL because the OS does not support AVX512 In commit 232d7a5e2dc50181294b927e2bc4b02e282725a8 we almost got the detection logic right. However, the XGETBV instruction would crash if Linux was started up with the option noxsave. have_vpclmulqdq(): Check for the XSAVE flag at the correct position and also for the AVX flag. This was tested on Ubuntu 22.04 by starting up its Linux 5.15 kernel with and without the noxsave option. --- mysys/crc32/crc32c_x86.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysys/crc32/crc32c_x86.cc b/mysys/crc32/crc32c_x86.cc index 3ddddf1303c..fb5dc19f7a5 100644 --- a/mysys/crc32/crc32c_x86.cc +++ b/mysys/crc32/crc32c_x86.cc @@ -39,7 +39,7 @@ extern "C" unsigned crc32c_sse42(unsigned crc, const void* buf, size_t size); constexpr uint32_t cpuid_ecx_SSE42= 1U << 20; constexpr uint32_t cpuid_ecx_SSE42_AND_PCLMUL= cpuid_ecx_SSE42 | 1U << 1; -constexpr uint32_t cpuid_ecx_XSAVE= 1U << 26; +constexpr uint32_t cpuid_ecx_AVX_AND_XSAVE= 1U << 28 | 1U << 27; static uint32_t cpuid_ecx() { @@ -395,7 +395,7 @@ static bool os_have_avx512() static ATTRIBUTE_NOINLINE bool have_vpclmulqdq(uint32_t cpuid_ecx) { - if (!(cpuid_ecx & cpuid_ecx_XSAVE) || !os_have_avx512()) + if ((~cpuid_ecx & cpuid_ecx_AVX_AND_XSAVE) || !os_have_avx512()) return false; # ifdef _MSC_VER int regs[4]; From 0b7d19d5002e8b7b2f7c97492dc3da3916d4a0b9 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 20 Aug 2024 16:12:02 +0200 Subject: [PATCH 02/10] MDEV-34785: Assertion failure in Item_func_or_sum::do_build_clone (Item_func_not_all) Missed method added. --- mysql-test/main/item_types.result | 9 +++++++++ mysql-test/main/item_types.test | 9 +++++++++ sql/item_cmpfunc.h | 2 ++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/main/item_types.result b/mysql-test/main/item_types.result index 0193d33be6d..a0068772cea 100644 --- a/mysql-test/main/item_types.result +++ b/mysql-test/main/item_types.result @@ -42,5 +42,14 @@ SELECT * FROM v WHERE f = '10.5.20'; f drop view v; # +# MDEV-34785: Assertion failure in Item_func_or_sum::do_build_clone +# (Item_func_not_all) +# +CREATE VIEW t AS SELECT 0 AS a; +SELECT * FROM t WHERE a=ALL (SELECT 0); +a +0 +DROP VIEW t; +# # End of 10.5 tests # diff --git a/mysql-test/main/item_types.test b/mysql-test/main/item_types.test index 2818ae582af..0a4100e9163 100644 --- a/mysql-test/main/item_types.test +++ b/mysql-test/main/item_types.test @@ -46,6 +46,15 @@ CREATE VIEW v AS SELECT version() AS f; SELECT * FROM v WHERE f = '10.5.20'; drop view v; +--echo # +--echo # MDEV-34785: Assertion failure in Item_func_or_sum::do_build_clone +--echo # (Item_func_not_all) +--echo # + +CREATE VIEW t AS SELECT 0 AS a; +SELECT * FROM t WHERE a=ALL (SELECT 0); +DROP VIEW t; + --echo # --echo # End of 10.5 tests --echo # diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index adbb00147dc..fd5c2bc9873 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -711,6 +711,8 @@ public: void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; test_sum_item= 0;}; bool empty_underlying_subquery(); Item *neg_transformer(THD *thd) override; + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; From eadf0f63a284ba4392089d9271eadf1ce2f62f04 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 21 Aug 2024 15:32:14 +0200 Subject: [PATCH 03/10] fix MDEV-34771 & MDEV-34776 removed duplicated methods --- sql/item.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sql/item.h b/sql/item.h index cddef65f4fd..511f86f5dbc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4706,7 +4706,6 @@ public: } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -4721,7 +4720,6 @@ public: { } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -4738,7 +4736,6 @@ public: { } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -4777,7 +4774,6 @@ public: } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -4797,7 +4793,6 @@ public: } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -4960,7 +4955,6 @@ public: void print(String *str, enum_query_type query_type) override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; From 1f040ae0485ba16746229f8db9ffbe1af947aa03 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 20 Aug 2024 11:31:58 +0300 Subject: [PATCH 04/10] MDEV-34043 Drastically slower query performance between CentOS (2sec) and Rocky (48sec) One cause of the slowdown is because the ftruncate call can be much slower on some systems. ftruncate() is called by Aria for internal temporary tables, tables created by the optimizer, when the upper level asks Aria to delete the previous result set. This is needed when some content from previous tables changes. I have now changed Aria so that for internal temporary tables we don't call ftruncate() anymore for maria_delete_all_rows(). I also had to update the Aria repair code to use the logical datafile size and not the on-disk datafile size, which may contain data from a previous result set. The repair code is called to create indexes for the internal temporary table after it is filled. I also replaced a call to mysql_file_size() with a pwrite() in _ma_bitmap_create_first(). Reviewer: Sergei Petrunia Tester: Dave Gosselin --- storage/maria/ma_bitmap.c | 18 +++++++++++------- storage/maria/ma_check.c | 26 ++++++++++++++++++++++---- storage/maria/ma_delete_all.c | 14 +++++++++++--- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 48a0545467c..613dcd18e02 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -3070,21 +3070,25 @@ my_bool _ma_check_if_right_bitmap_type(MARIA_HA *info, int _ma_bitmap_create_first(MARIA_SHARE *share) { uint block_size= share->bitmap.block_size; + size_t error; File file= share->bitmap.file.file; - uchar marker[CRC_SIZE]; + uchar *temp_buff; + + if (!(temp_buff= (uchar*) my_alloca(block_size))) + return 1; + bzero(temp_buff, block_size); /* Next write operation of the page will write correct CRC if it is needed */ - int4store(marker, MARIA_NO_CRC_BITMAP_PAGE); + int4store(temp_buff + block_size - CRC_SIZE, MARIA_NO_CRC_BITMAP_PAGE); - if (mysql_file_chsize(file, block_size - sizeof(marker), - 0, MYF(MY_WME)) || - my_pwrite(file, marker, sizeof(marker), - block_size - sizeof(marker), - MYF(MY_NABP | MY_WME))) + error= my_pwrite(file, temp_buff, block_size, 0, MYF(MY_NABP | MY_WME)); + my_afree(temp_buff); + if (error) return 1; + share->state.state.data_file_length= block_size; _ma_bitmap_delete_all(share); return 0; diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 0c80b58d7e3..7f104325d00 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -418,6 +418,8 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) /* We cannot check file sizes for S3 */ DBUG_RETURN(0); } + /* We should never come here with internal temporary tables */ + DBUG_ASSERT(!share->internal_table); if (!(param->testflag & T_SILENT)) puts("- check file-size"); @@ -713,6 +715,8 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_PAGE ma_page; DBUG_ENTER("chk_index_down"); + DBUG_ASSERT(!share->internal_table); + /* Key blocks must lay within the key file length entirely. */ if (page + keyinfo->block_length > share->state.state.key_file_length) { @@ -2464,7 +2468,16 @@ static int initialize_variables_for_repair(HA_CHECK *param, return 1; /* calculate max_records */ - sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); + if (!share->internal_table) + { + /* Get real file size */ + sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); + } + else + { + /* For internal temporary files we are using the logical file length */ + sort_info->filelength= share->state.state.data_file_length; + } param->max_progress= sort_info->filelength; if ((param->testflag & T_CREATE_MISSING_KEYS) || @@ -2860,7 +2873,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, { fputs(" \r",stdout); fflush(stdout); } - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) { _ma_check_print_warning(param, @@ -4168,7 +4182,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, if (param->testflag & T_CALC_CHECKSUM) share->state.state.checksum=param->glob_crc; - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) _ma_check_print_warning(param, "Can't change size of indexfile, error: %d", @@ -4706,7 +4721,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, if (param->testflag & T_CALC_CHECKSUM) share->state.state.checksum=param->glob_crc; - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) _ma_check_print_warning(param, "Can't change size of indexfile, error: %d", @@ -6108,6 +6124,8 @@ int maria_test_if_almost_full(MARIA_HA *info) { MARIA_SHARE *share= info->s; + DBUG_ASSERT(!share->internal_table); + if (share->options & HA_OPTION_COMPRESS_RECORD) return 0; return mysql_file_seek(share->kfile.file, 0L, MY_SEEK_END, diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c index c1019c01c66..d799e213d5f 100644 --- a/storage/maria/ma_delete_all.c +++ b/storage/maria/ma_delete_all.c @@ -103,9 +103,17 @@ int maria_delete_all_rows(MARIA_HA *info) #endif if (_ma_flush_table_files(info, MARIA_FLUSH_DATA|MARIA_FLUSH_INDEX, - FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED) || - mysql_file_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) || - mysql_file_chsize(share->kfile.file, share->base.keystart, 0, MYF(MY_WME))) + FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED)) + goto err; + /* + Avoid truncate of internal temporary tables as this can have a big + performance overhead when called by mysql_handle_single_derived() + tables in MariaDB as part of split materialization. + */ + if (!share->internal_table && + (mysql_file_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) || + mysql_file_chsize(share->kfile.file, share->base.keystart, 0, + MYF(MY_WME)))) goto err; if (_ma_initialize_data_file(share, info->dfile.file)) From b4c2e239545f0162f8613acb0a66aee8b5dce0d4 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Sat, 3 Aug 2024 03:51:47 +0200 Subject: [PATCH 05/10] MDEV-34696: do_gco_wait() completes too early on InnoDB dict stats updates Before doing mark_start_commit(), check that there is no pending deadlock kill. If there is a pending kill, we won't commit (we will abort, roll back, and retry). Then we should not mark the commit as started, since that could potentially make the following GCO start too early, before we completed the commit after the retry. This condition could trigger in some corner cases, where InnoDB would take temporarily table/row locks that are released again immediately, not held until the transaction commits. This happens with dict_stats updates and possibly auto-increment locks. Such locks can be passed to thd_rpl_deadlock_check() and cause a deadlock kill to be scheduled in the background. But since the blocking locks are held only temporarily, they can be released before the background kill happens. This way, the kill can be delayed until after mark_start_commit() has been called. Thus we need to check the synchronous indication rgi->killed_for_retry, not just the asynchroneous thd->killed. Signed-off-by: Kristian Nielsen --- sql/rpl_parallel.cc | 20 ++++++++++++++++---- sql/rpl_rli.cc | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 1cfdf96ee3b..9c4222d7817 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1450,11 +1450,23 @@ handle_rpl_parallel_thread(void *arg) after mark_start_commit(), we have to unmark, which has at least a theoretical possibility of leaving a window where it looks like all transactions in a GCO have started committing, while in fact one - will need to rollback and retry. This is not supposed to be possible - (since there is a deadlock, at least one transaction should be - blocked from reaching commit), but this seems a fragile ensurance, - and there were historically a number of subtle bugs in this area. + will need to rollback and retry. + + Normally this will not happen, since the kill is there to resolve a + deadlock that is preventing at least one transaction from proceeding. + One case it can happen is with InnoDB dict stats update, which can + temporarily cause transactions to block each other, but locks are + released immediately, they don't linger until commit. There could be + other similar cases, there were historically a number of subtle bugs + in this area. + + But once we start the commit, we can expect that no new lock + conflicts will be introduced. So by handling any lingering deadlock + kill at this point just before mark_start_commit(), we should be + robust even towards spurious deadlock kills. */ + if (rgi->killed_for_retry != rpl_group_info::RETRY_KILL_NONE) + wait_for_pending_deadlock_kill(thd, rgi); if (!thd->killed) { DEBUG_SYNC(thd, "rpl_parallel_before_mark_start_commit"); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 9d4e09a362c..8284b07f7ff 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -2518,6 +2518,23 @@ rpl_group_info::unmark_start_commit() e= this->parallel_entry; mysql_mutex_lock(&e->LOCK_parallel_entry); + /* + Assert that we have not already wrongly completed this GCO and signalled + the next one to start, only to now unmark and make the signal invalid. + This is to catch problems like MDEV-34696. + + The error inject rpl_parallel_simulate_temp_err_xid is used to test this + precise situation, that we handle it gracefully if it somehow occurs in a + release build. So disable the assert in this case. + */ +#ifndef DBUG_OFF + bool allow_unmark_after_complete= false; + DBUG_EXECUTE_IF("rpl_parallel_simulate_temp_err_xid", + allow_unmark_after_complete= true;); + DBUG_ASSERT(!gco->next_gco || + gco->next_gco->wait_count > e->count_committing_event_groups || + allow_unmark_after_complete); +#endif --e->count_committing_event_groups; mysql_mutex_unlock(&e->LOCK_parallel_entry); } From 33854d7324b982e0dea1378c9c153cd1e276ddfc Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Sat, 3 Aug 2024 12:16:32 +0200 Subject: [PATCH 06/10] Restore skiping rpl.rpl_mdev6020 under Valgrind (Revert a change done by mistake when XtraDB was removed.) Signed-off-by: Kristian Nielsen --- mysql-test/suite/rpl/t/rpl_mdev6020.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_mdev6020.test b/mysql-test/suite/rpl/t/rpl_mdev6020.test index ec3fd92f817..314059a5a49 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev6020.test +++ b/mysql-test/suite/rpl/t/rpl_mdev6020.test @@ -1,3 +1,5 @@ +# Test applies a large binlog, takes long under Valgrind with little benefit. +--source include/not_valgrind.inc --source include/have_innodb.inc --source include/have_partition.inc --source include/have_binlog_format_mixed_or_row.inc From 7dc4ea5649eed222c2427798893f90664cbec647 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Fri, 16 Aug 2024 21:58:49 +0200 Subject: [PATCH 07/10] Fix sporadic test failure in rpl.rpl_create_drop_event Depending on timing, an extra event run could start just when the event scheduler is shut down and delay running until after the table has been dropped; this would cause the test to fail with a "table does not exist" error in the log. Signed-off-by: Kristian Nielsen --- mysql-test/suite/rpl/t/rpl_create_drop_event.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_event.test b/mysql-test/suite/rpl/t/rpl_create_drop_event.test index 96a7e82d6f7..79bb0ffec90 100644 --- a/mysql-test/suite/rpl/t/rpl_create_drop_event.test +++ b/mysql-test/suite/rpl/t/rpl_create_drop_event.test @@ -14,6 +14,12 @@ SET GLOBAL event_scheduler=on; let $wait_condition= SELECT count(*)>0 FROM t1; --source include/wait_condition.inc SET GLOBAL event_scheduler=off; +# If the time rolls to the next whole second just at this point, a new event +# run may be scheduled. Wait for this to disappear, otherwise we see occasional +# test failures if the table gets dropped before the extra event run completes. +# Expect 5 connections: default, master, master1, server_1, binlog dump thread +--let $wait_condition= SELECT COUNT(*) = 5 FROM INFORMATION_SCHEMA.PROCESSLIST; +--source include/wait_condition.inc SELECT DISTINCT a FROM t1; DELETE FROM t1; From 214e6c5b3d05812e9f1de6d0a22955d18911a076 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 19 Aug 2024 20:37:34 +0200 Subject: [PATCH 08/10] Fix sporadic failure of test case rpl.rpl_old_master Remove the test for MDEV-14528. This is supposed to test that parallel replication from pre-10.0 master will update Seconds_Behind_Master. But after MDEV-12179 the SQL thread is blocked from even beginning to fetch events from the relay log due to FLUSH TABLES WITH READ LOCK, so the test case is no longer testing what is was intended to. And pre-10.0 versions are long since out of support, so does not seem worthwhile to try to rewrite the test to work another way. The root cause of the test failure is MDEV-34778. Briefly, depending on exact timing during slave stop, the rli->sql_thread_caught_up flag may end up with different value. If it ends up as "true", this causes Seconds_Behind_Master to be 0 during next slave start; and this caused test case timeout as the test was waiting for Seconds_Behind_Master to become non-zero. Signed-off-by: Kristian Nielsen --- mysql-test/suite/rpl/r/rpl_old_master.result | 3 --- mysql-test/suite/rpl/t/rpl_old_master.test | 7 ------- 2 files changed, 10 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_old_master.result b/mysql-test/suite/rpl/r/rpl_old_master.result index f985bee6832..dd3de4d327b 100644 --- a/mysql-test/suite/rpl/r/rpl_old_master.result +++ b/mysql-test/suite/rpl/r/rpl_old_master.result @@ -9,10 +9,7 @@ connection slave; SET @old_parallel= @@GLOBAL.slave_parallel_threads; SET GLOBAL slave_parallel_threads=10; CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; -FLUSH TABLES WITH READ LOCK; include/start_slave.inc -include/wait_for_slave_param.inc [Seconds_Behind_Master] -UNLOCK TABLES; connection master; CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t2 VALUES (1); diff --git a/mysql-test/suite/rpl/t/rpl_old_master.test b/mysql-test/suite/rpl/t/rpl_old_master.test index 6ddc227fc14..97721d5387a 100644 --- a/mysql-test/suite/rpl/t/rpl_old_master.test +++ b/mysql-test/suite/rpl/t/rpl_old_master.test @@ -28,14 +28,7 @@ SET GLOBAL slave_parallel_threads=10; --replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; -# Block execution yet when the blocked query timestamp has been already accounted -FLUSH TABLES WITH READ LOCK; --source include/start_slave.inc ---let $slave_param = Seconds_Behind_Master ---let $slave_param_value = 1 ---let $slave_param_comparison= >= ---source include/wait_for_slave_param.inc -UNLOCK TABLES; --connection master CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; From 25e0224814c8883dc22cf602586e8d2c76f5e359 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 19 Aug 2024 20:58:09 +0200 Subject: [PATCH 09/10] Skip mariabackup.slave_provision_nolock in --valgrind, it uses a lot of CPU Signed-off-by: Kristian Nielsen --- mysql-test/suite/mariabackup/slave_provision_nolock.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/mariabackup/slave_provision_nolock.test b/mysql-test/suite/mariabackup/slave_provision_nolock.test index 618f313290c..0253a6c0c2d 100644 --- a/mysql-test/suite/mariabackup/slave_provision_nolock.test +++ b/mysql-test/suite/mariabackup/slave_provision_nolock.test @@ -1,5 +1,7 @@ --source include/have_innodb.inc --source include/have_log_bin.inc +# Test does a lot of queries that take a lot of CPU under Valgrind. +--source include/not_valgrind.inc call mtr.add_suppression("Can't init tc log"); call mtr.add_suppression("Aborting"); From 8642453ce6ab1d8028ff1ac9e10f7b08418c12cb Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 19 Aug 2024 22:27:44 +0200 Subject: [PATCH 10/10] Fix sporadic failure of test case rpl.rpl_start_stop_slave The test was expecting the I/O thread to be in a specific state, but thread scheduling may cause it to not yet have reached that state. So just have a loop that waits for the expected state to occur. Signed-off-by: Kristian Nielsen --- mysql-test/suite/rpl/t/rpl_start_stop_slave.test | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test index 23b25b1bf85..ce7d51ca43d 100644 --- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test @@ -19,7 +19,17 @@ --source include/master-slave.inc connection slave; ---let $connection_id=`SELECT id FROM information_schema.processlist where state LIKE 'Waiting for master to send event'` +--let $i= 100 +while ($i > 0) { + dec $i; + --let $connection_id=`SELECT id FROM information_schema.processlist where state LIKE 'Waiting for master to send event'` + if ($connection_id) { + let $i= 0; + } + if ($i > 0) { + --sleep 0.1 + } +} if(!$connection_id) {