Skip to content

Commit

Permalink
MDEV-27983: InnoDB hangs after loading a ROW_FORMAT=COMPRESSED page
Browse files Browse the repository at this point in the history
If multiple threads invoke buf_page_get_low() on a ROW_FORMAT=COMPRESSED
page that does not reside in the buffer pool, then one of the threads
will end up acquiring an exclusive page latch (the "if" statement
right before the new wait_for_unzip: label) and other threads will
end up waiting for a shared latch while holding a buffer-fix.
The exclusive latch holder would then wait for the buffer-fixes to
be released while the buffer-fix holders are waiting for the shared latch.

buf_page_get_low(): Prevent the hang that was introduced
in commit 9436c77 (MDEV-27058),
by releasing the buffer-fix, sleeping some time, and retrying the
page lookup.
  • Loading branch information
dr-m committed Aug 31, 2022
1 parent bdf62ec commit 9203249
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion storage/innobase/buf/buf0buf.cc
Expand Up @@ -2529,6 +2529,9 @@ buf_page_get_low(
return nullptr;
}

if (UNIV_UNLIKELY(!block->page.frame)) {
goto wait_for_unzip;
}
/* A read-fix is released after block->page.lock
in buf_page_t::read_complete() or
buf_pool_t::corrupted_evict(), or
Expand Down Expand Up @@ -2559,7 +2562,7 @@ buf_page_get_low(
mysql_mutex_lock(&buf_pool.mutex);
block->unfix();

if (!buf_LRU_free_page(&block->page, true)) {
if (!buf_LRU_free_page(&block->page, true)) {
ut_ad(0);
}

Expand All @@ -2577,6 +2580,7 @@ buf_page_get_low(

if (UNIV_UNLIKELY(!block->page.frame)) {
if (!block->page.lock.x_lock_try()) {
wait_for_unzip:
/* The page is being read or written, or
another thread is executing buf_zip_decompress()
in buf_page_get_low() on it. */
Expand Down

0 comments on commit 9203249

Please sign in to comment.