summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-11-05 08:09:33 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-11-05 08:09:33 +0200
commit9b967c4c31555174a293922d4717d83b7d68bc76 (patch)
tree605edc037f0059e95721e26b762ae990129a57b1
parent20f7fc6ef2da695cdfefbf43f7ccdc63cbacb358 (diff)
downloadmariadb-git-9b967c4c31555174a293922d4717d83b7d68bc76.tar.gz
MDEV-26826 fixup: ROW_FORMAT=COMPRESSED may corrupt buf_pool.page_hash
In commit c091a0bc8da87045f10bfc96618ed7194768fa2d we removed the use of the HASH_ macros for inserting into buf_pool.page_hash, or accessing buf_page_t::hash. However, the binary buddy allocator for block->page.zip.data would still use the HASH_ macros. HASH_INSERT and not HASH_DELETE would reset the next-block pointer to the null pointer. Our replacement of HASH_DELETE() will reset the next-block pointer, and the replacement of HASH_INSERT() assumes that the pointer is the null pointer. buf_LRU_block_free_non_file_page(): Assert that the next-block pointer is the null pointer. buf_buddy_block_free(): Reset the pointer before invoking buf_LRU_block_free_non_file_page(). Without this, the added assertion would fail in the test encryption.innochecksum.
-rw-r--r--storage/innobase/buf/buf0buddy.cc1
-rw-r--r--storage/innobase/buf/buf0buf.cc2
-rw-r--r--storage/innobase/buf/buf0lru.cc1
3 files changed, 3 insertions, 1 deletions
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 6f4b4554518..125dac5333e 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -362,6 +362,7 @@ buf_buddy_block_free(void* buf)
ut_ad(bpage->in_zip_hash);
ut_d(bpage->in_zip_hash = false);
HASH_DELETE(buf_page_t, hash, &buf_pool.zip_hash, fold, bpage);
+ bpage->hash = nullptr;
ut_d(memset(buf, 0, srv_page_size));
MEM_UNDEFINED(buf, srv_page_size);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index d03a92cc7a5..687990d6885 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -219,7 +219,7 @@ buf_pool.LRU.
The chains of free memory blocks (buf_pool.zip_free[]) are used by
the buddy allocator (buf0buddy.cc) to keep track of currently unused
-memory blocks of size sizeof(buf_page_t)..srv_page_size / 2. These
+memory blocks of size UNIV_PAGE_SIZE_MIN..srv_page_size / 2. These
blocks are inside the srv_page_size-sized memory blocks of type
BUF_BLOCK_MEMORY that the buddy allocator requests from the buffer
pool. The buddy allocator is solely used for allocating control
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 77d367074b0..250c12bea78 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1010,6 +1010,7 @@ buf_LRU_block_free_non_file_page(
ut_ad(!block->page.in_free_list);
ut_ad(!block->page.oldest_modification());
ut_ad(!block->page.in_LRU_list);
+ ut_ad(!block->page.hash);
block->page.set_state(BUF_BLOCK_NOT_USED);