Commit 7c524d44 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-25371 Potential hang in wsrep_is_BF_lock_timeout()

In commit e71e6133 (MDEV-24671),
lock_sys.wait_mutex was moved above lock_sys.mutex
(which was later replaced with lock_sys.latch) in the latching order.

In commit 7cf4419f (MDEV-24789),
a potential hang was introduced to Galera. The function lock_wait()
would hold lock_sys.wait_mutex while invoking wsrep_is_BF_lock_timeout(),
which in turn could acquire LockMutexGuard for some diagnostic printout.

wsrep_is_BF_lock_timeout(): Do not invoke trx_print_latched() or
LockMutexGuard.

lock_sys_t::wr_lock(), lock_sys_t::rd_lock(): Assert that the current
thread is not holding lock_sys.wait_mutex.
Unfortunately, RW-locks are not covered by SAFE_MUTEX.

Reviewed by: Jan Lindström
parent 1900c2ed
...@@ -703,6 +703,7 @@ class lock_sys_t ...@@ -703,6 +703,7 @@ class lock_sys_t
/** Acquire exclusive lock_sys.latch */ /** Acquire exclusive lock_sys.latch */
void wr_lock() void wr_lock()
{ {
mysql_mutex_assert_not_owner(&wait_mutex);
ut_ad(!is_writer()); ut_ad(!is_writer());
latch.wr_lock(); latch.wr_lock();
ut_ad(!writer.exchange(os_thread_get_curr_id(), ut_ad(!writer.exchange(os_thread_get_curr_id(),
...@@ -718,6 +719,7 @@ class lock_sys_t ...@@ -718,6 +719,7 @@ class lock_sys_t
/** Acquire shared lock_sys.latch */ /** Acquire shared lock_sys.latch */
void rd_lock() void rd_lock()
{ {
mysql_mutex_assert_not_owner(&wait_mutex);
ut_ad(!is_writer()); ut_ad(!is_writer());
latch.rd_lock(); latch.rd_lock();
ut_ad(!writer.load(std::memory_order_relaxed)); ut_ad(!writer.load(std::memory_order_relaxed));
......
...@@ -391,6 +391,7 @@ void lock_sys_t::create(ulint n_cells) ...@@ -391,6 +391,7 @@ void lock_sys_t::create(ulint n_cells)
/** Acquire exclusive lock_sys.latch */ /** Acquire exclusive lock_sys.latch */
void lock_sys_t::wr_lock(const char *file, unsigned line) void lock_sys_t::wr_lock(const char *file, unsigned line)
{ {
mysql_mutex_assert_not_owner(&wait_mutex);
latch.wr_lock(file, line); latch.wr_lock(file, line);
ut_ad(!writer.exchange(os_thread_get_curr_id(), std::memory_order_relaxed)); ut_ad(!writer.exchange(os_thread_get_curr_id(), std::memory_order_relaxed));
} }
...@@ -405,6 +406,7 @@ void lock_sys_t::wr_unlock() ...@@ -405,6 +406,7 @@ void lock_sys_t::wr_unlock()
/** Acquire shared lock_sys.latch */ /** Acquire shared lock_sys.latch */
void lock_sys_t::rd_lock(const char *file, unsigned line) void lock_sys_t::rd_lock(const char *file, unsigned line)
{ {
mysql_mutex_assert_not_owner(&wait_mutex);
latch.rd_lock(file, line); latch.rd_lock(file, line);
ut_ad(!writer.load(std::memory_order_relaxed)); ut_ad(!writer.load(std::memory_order_relaxed));
ut_d(readers.fetch_add(1, std::memory_order_relaxed)); ut_d(readers.fetch_add(1, std::memory_order_relaxed));
...@@ -549,10 +551,6 @@ ATTRIBUTE_NOINLINE static bool wsrep_is_BF_lock_timeout(const trx_t &trx) ...@@ -549,10 +551,6 @@ ATTRIBUTE_NOINLINE static bool wsrep_is_BF_lock_timeout(const trx_t &trx)
ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx.id) ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx.id)
<< " query: " << wsrep_thd_query(trx.mysql_thd); << " query: " << wsrep_thd_query(trx.mysql_thd);
{
LockMutexGuard g{SRW_LOCK_CALL};
trx_print_latched(stderr, &trx, 3000);
}
srv_print_innodb_monitor= true; srv_print_innodb_monitor= true;
srv_print_innodb_lock_monitor= true; srv_print_innodb_lock_monitor= true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment