Commit 638ede5b authored by Marko Mäkelä's avatar Marko Mäkelä Committed by Sergei Golubchik

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.
parent f13f9663
/***************************************************************************** /*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. 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 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 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) ...@@ -991,10 +991,13 @@ fil_crypt_read_crypt_data(fil_space_t* space)
const ulint zip_size = space->zip_size(); const ulint zip_size = space->zip_size();
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
if (buf_block_t* block = buf_page_get(page_id_t(space->id, 0), if (buf_block_t* block = buf_page_get_gen(page_id_t(space->id, 0),
zip_size, RW_S_LATCH, &mtr)) { zip_size, RW_S_LATCH,
nullptr,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr)) {
mutex_enter(&fil_system.mutex); mutex_enter(&fil_system.mutex);
if (!space->crypt_data) { if (!space->crypt_data && !space->is_stopping()) {
space->crypt_data = fil_space_read_crypt_data( space->crypt_data = fil_space_read_crypt_data(
zip_size, block->frame); zip_size, block->frame);
} }
......
...@@ -410,8 +410,11 @@ xdes_get_descriptor_const( ...@@ -410,8 +410,11 @@ xdes_get_descriptor_const(
const ulint zip_size = space->zip_size(); const ulint zip_size = space->zip_size();
if (buf_block_t* block = buf_page_get(page_id_t(space->id, page), if (buf_block_t* block = buf_page_get_gen(page_id_t(space->id, page),
zip_size, RW_S_LATCH, mtr)) { zip_size, RW_S_LATCH,
nullptr,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, mtr)) {
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
ut_ad(page != 0 || space->free_limit == mach_read_from_4( ut_ad(page != 0 || space->free_limit == mach_read_from_4(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment