summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-08-29 15:14:59 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-08-29 15:14:59 +0300
commit8ba5e8510471acc9911ce8a1ef3dd385ac1be7f3 (patch)
tree24ee4bab47111c752cbe4f46c1f6f7f14566d4bb
parent0fbcb0a2b87d8807b85fec85507074bcda3d4da9 (diff)
downloadmariadb-git-bb-10.6-MDEV-27983.tar.gz
MDEV-27983: InnoDB hangs after loading a ROW_FORMAT=COMPRESSED pagebb-10.6-MDEV-27983
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 9436c778c3adba7c29dab5649668433d71e086f2 (MDEV-27058), by releasing the buffer-fix, sleeping some time, and retrying the page lookup.
-rw-r--r--storage/innobase/buf/buf0buf.cc6
1 files changed, 5 insertions, 1 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index eaf0f955a1f..0d0978c0c1d 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2529,6 +2529,9 @@ ignore_block:
return nullptr;
}
+ if (state != buf_page_t::READ_FIX + 1 && !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
@@ -2559,7 +2562,7 @@ ignore_block:
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);
}
@@ -2577,6 +2580,7 @@ ignore_block:
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. */