mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-22370 safe_mutex: Trying to lock uninitialized mutex at /data/src/10.4-bug/sql/rpl_parallel.cc, line 470 upon shutdown during FTWRL
Problem:- When we issue FTWRL with shutdown in parallel, there is race between FTWRL and shutdown. Shutdown might destroy the mutex (pool->LOCK_rpl_thread_pool) before FTWRL can lock it. So we can get crash on FTWRL thread Solution:- mysql_mutex_destroy(pool->LOCK_rpl_thread_pool) should wait for FTWRL thread to complete its work , and then destroy. So slave_prepare_for_shutdown will just deactivate the pool, and mutex is destroyed later in end_slave()
This commit is contained in:
4
mysql-test/r/mdev_22370.result
Normal file
4
mysql-test/r/mdev_22370.result
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
connect con1,localhost,root,,;
|
||||||
|
SET DEBUG_DBUG='+d,mark_busy_mdev_22370';
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
connection default;
|
17
mysql-test/t/mdev_22370.test
Normal file
17
mysql-test/t/mdev_22370.test
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# MDEV-22370 safe_mutex: Trying to lock uninitialized mutex at
|
||||||
|
# /data/src/10.4-bug/sql/rpl_parallel.cc, line 470 upon shutdown during FTWRL
|
||||||
|
#
|
||||||
|
# Purpose of this test case to test crash while FTWRL and shutdown is in race
|
||||||
|
# condition
|
||||||
|
# Shutdown can execute first and destroy the mutex making mutex_lock in pool_mark_busy
|
||||||
|
# to crash
|
||||||
|
|
||||||
|
--source include/have_debug.inc
|
||||||
|
--connect (con1,localhost,root,,)
|
||||||
|
SET DEBUG_DBUG='+d,mark_busy_mdev_22370';
|
||||||
|
--send
|
||||||
|
FLUSH TABLES WITH READ LOCK;
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
--source include/restart_mysqld.inc
|
@ -455,6 +455,7 @@ pool_mark_busy(rpl_parallel_thread_pool *pool, THD *thd)
|
|||||||
So we protect the infrequent operations of FLUSH TABLES WITH READ LOCK and
|
So we protect the infrequent operations of FLUSH TABLES WITH READ LOCK and
|
||||||
pool size changes with this condition wait.
|
pool size changes with this condition wait.
|
||||||
*/
|
*/
|
||||||
|
DBUG_EXECUTE_IF("mark_busy_mdev_22370",my_sleep(1000000););
|
||||||
mysql_mutex_lock(&pool->LOCK_rpl_thread_pool);
|
mysql_mutex_lock(&pool->LOCK_rpl_thread_pool);
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
@ -2001,10 +2002,24 @@ rpl_parallel_thread_pool::init(uint32 size)
|
|||||||
|
|
||||||
void
|
void
|
||||||
rpl_parallel_thread_pool::destroy()
|
rpl_parallel_thread_pool::destroy()
|
||||||
|
{
|
||||||
|
deactivate();
|
||||||
|
destroy_cond_mutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpl_parallel_thread_pool::deactivate()
|
||||||
{
|
{
|
||||||
if (!inited)
|
if (!inited)
|
||||||
return;
|
return;
|
||||||
rpl_parallel_change_thread_count(this, 0, 1);
|
rpl_parallel_change_thread_count(this, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpl_parallel_thread_pool::destroy_cond_mutex()
|
||||||
|
{
|
||||||
|
if (!inited)
|
||||||
|
return;
|
||||||
mysql_mutex_destroy(&LOCK_rpl_thread_pool);
|
mysql_mutex_destroy(&LOCK_rpl_thread_pool);
|
||||||
mysql_cond_destroy(&COND_rpl_thread_pool);
|
mysql_cond_destroy(&COND_rpl_thread_pool);
|
||||||
inited= false;
|
inited= false;
|
||||||
|
@ -240,6 +240,8 @@ struct rpl_parallel_thread_pool {
|
|||||||
rpl_parallel_thread_pool();
|
rpl_parallel_thread_pool();
|
||||||
int init(uint32 size);
|
int init(uint32 size);
|
||||||
void destroy();
|
void destroy();
|
||||||
|
void deactivate();
|
||||||
|
void destroy_cond_mutex();
|
||||||
struct rpl_parallel_thread *get_thread(rpl_parallel_thread **owner,
|
struct rpl_parallel_thread *get_thread(rpl_parallel_thread **owner,
|
||||||
rpl_parallel_entry *entry);
|
rpl_parallel_entry *entry);
|
||||||
void release_thread(rpl_parallel_thread *rpt);
|
void release_thread(rpl_parallel_thread *rpt);
|
||||||
|
@ -977,7 +977,7 @@ void slave_prepare_for_shutdown()
|
|||||||
mysql_mutex_unlock(&LOCK_active_mi);
|
mysql_mutex_unlock(&LOCK_active_mi);
|
||||||
// It's safe to destruct worker pool now when
|
// It's safe to destruct worker pool now when
|
||||||
// all driver threads are gone.
|
// all driver threads are gone.
|
||||||
global_rpl_thread_pool.destroy();
|
global_rpl_thread_pool.deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user