diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-02-15 09:37:01 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-02-15 17:00:19 +0100 |
commit | 638ede5bef6f2769aedf84a92222f2fd2f313a9a (patch) | |
tree | b4b9a3888b589ab651c8e191fce2134d84530f1f /storage/innobase | |
parent | f13f9663042c19811d156043f1931a63aba44076 (diff) | |
download | mariadb-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.cc | 11 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 7 |
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( |