Commit c410f7aa authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-27414 Server may hang when innodb_undo_log_truncate=ON

trx_purge_truncate_history(): Avoid a deadlock with
buf_pool_t::release_freed_page(). Page latches are not supposed
to be waited for while holding a mutex like buf_pool.mutex or
buf_pool.flush_list_mutex.

This regression was caused by
commit aaef2e1d (MDEV-27058).
Before that, trx_purge_truncate_history() would buffer-fix the block,
release buf_pool.flush_list_mutex, and then wait for the
exclusive page latch.

This bug led to occasional failures of the test
innodb.undo_truncate_recover.
parent 30b917d3
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -705,7 +705,16 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history() ...@@ -705,7 +705,16 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
{ {
auto block= reinterpret_cast<buf_block_t*>(bpage); auto block= reinterpret_cast<buf_block_t*>(bpage);
ut_ad(buf_pool.is_uncompressed(block)); ut_ad(buf_pool.is_uncompressed(block));
bpage->lock.x_lock(); if (!bpage->lock.x_lock_try())
{
/* Let buf_pool_t::release_freed_page() proceed. */
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
std::this_thread::yield();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
rescan:
bpage= UT_LIST_GET_LAST(buf_pool.flush_list);
continue;
}
buf_pool.flush_hp.set(prev); buf_pool.flush_hp.set(prev);
mysql_mutex_unlock(&buf_pool.flush_list_mutex); mysql_mutex_unlock(&buf_pool.flush_list_mutex);
...@@ -728,11 +737,8 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history() ...@@ -728,11 +737,8 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
} }
if (prev != buf_pool.flush_hp.get()) if (prev != buf_pool.flush_hp.get())
{
/* Rescan, because we may have lost the position. */ /* Rescan, because we may have lost the position. */
bpage= UT_LIST_GET_LAST(buf_pool.flush_list); goto rescan;
continue;
}
} }
bpage= prev; bpage= prev;
......
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