summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-02-15 09:37:01 +0200
committerSergei Golubchik <serg@mariadb.org>2021-02-15 17:00:19 +0100
commit638ede5bef6f2769aedf84a92222f2fd2f313a9a (patch)
treeb4b9a3888b589ab651c8e191fce2134d84530f1f /storage/innobase
parentf13f9663042c19811d156043f1931a63aba44076 (diff)
downloadmariadb-git-638ede5bef6f2769aedf84a92222f2fd2f313a9a.tar.gz
MDEV-24864 Fatal error in buf_page_get_low() / fseg_page_is_free()
The fix of MDEV-24569 and MDEV-24695 introduced a race condition when a table is being rebuilt or dropped during the fseg_page_is_free() check. The server would occasionally crash during the execution of the test encryption.create_or_replace. The fil_space_t::STOPPING flag can be set by DDL operations. Normally, such concurrent operations are prevented by a metadata lock (MDL). However, neither the change buffer merge nor the fil_crypt_thread() are protected by MDL. fil_crypt_read_crypt_data(), xdes_get_descriptor_const(): Pass the BUF_GET_POSSIBLY_FREED flag to avoid the fatal error in buf_page_get_low() if a DDL operation was just initiated.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/fil/fil0crypt.cc11
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc7
2 files changed, 12 insertions, 6 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 2a8fa875e90..be0e45f276c 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2020, MariaDB Corporation.
+Copyright (c) 2014, 2021, MariaDB Corporation.
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
@@ -991,10 +991,13 @@ fil_crypt_read_crypt_data(fil_space_t* space)
const ulint zip_size = space->zip_size();
mtr_t mtr;
mtr.start();
- if (buf_block_t* block = buf_page_get(page_id_t(space->id, 0),
- zip_size, RW_S_LATCH, &mtr)) {
+ if (buf_block_t* block = buf_page_get_gen(page_id_t(space->id, 0),
+ zip_size, RW_S_LATCH,
+ nullptr,
+ BUF_GET_POSSIBLY_FREED,
+ __FILE__, __LINE__, &mtr)) {
mutex_enter(&fil_system.mutex);
- if (!space->crypt_data) {
+ if (!space->crypt_data && !space->is_stopping()) {
space->crypt_data = fil_space_read_crypt_data(
zip_size, block->frame);
}
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 650bf99695e..34464e38b21 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -410,8 +410,11 @@ xdes_get_descriptor_const(
const ulint zip_size = space->zip_size();
- if (buf_block_t* block = buf_page_get(page_id_t(space->id, page),
- zip_size, RW_S_LATCH, mtr)) {
+ if (buf_block_t* block = buf_page_get_gen(page_id_t(space->id, page),
+ zip_size, RW_S_LATCH,
+ nullptr,
+ BUF_GET_POSSIBLY_FREED,
+ __FILE__, __LINE__, mtr)) {
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
ut_ad(page != 0 || space->free_limit == mach_read_from_4(