Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDEV-32371 Deadlock between buf_page_get_zip() and buf_pool_t::corrupted_evict() #2866

Merged
merged 1 commit into from Nov 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 14 additions & 7 deletions storage/innobase/buf/buf0buf.cc
Expand Up @@ -2235,14 +2235,21 @@ buf_page_t* buf_page_get_zip(const page_id_t page_id, ulint zip_size)

if (discard_attempted || !bpage->frame)
{
/* Even when we are holding a hash_lock, it should be
acceptable to wait for a page S-latch here, because
buf_page_t::read_complete() will not wait for buf_pool.mutex,
and because S-latch would not conflict with a U-latch
that would be protecting buf_page_t::write_complete(). */
bpage->lock.s_lock();
const bool got_s_latch= bpage->lock.s_lock_try();
hash_lock.unlock_shared();
break;
if (UNIV_LIKELY(got_s_latch))
break;
/* We may fail to acquire bpage->lock because
buf_page_t::read_complete() may be invoking
buf_pool_t::corrupted_evict() on this block, which it would
hold an exclusive latch on.

Let us aqcuire and release buf_pool.mutex to ensure that any
buf_pool_t::corrupted_evict() will proceed before we reacquire
the hash_lock that it could be waiting for. */
mysql_mutex_lock(&buf_pool.mutex);
mysql_mutex_unlock(&buf_pool.mutex);
goto lookup;
}

hash_lock.unlock_shared();
Expand Down