mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-34453 Trying to read 16384 bytes at 70368744161280 outside the bounds of the file: ./ibdata1
The issue is caused by a race between buf_page_create_low getting the
page from buffer pool hash and buf_LRU_free_page evicting it from LRU.
The issue is introduced in 10.6 by MDEV-27058
commit aaef2e1d8c
MDEV-27058: Reduce the size of buf_block_t and buf_page_t
The solution is buffer fix the page before releasing buffer pool mutex
in buf_page_create_low when x_lock_try fails to acquire the page latch.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
--source include/no_valgrind_without_big.inc
|
--source include/no_valgrind_without_big.inc
|
||||||
|
--source include/maybe_debug.inc
|
||||||
######## t/ddl_innodb.test ######
|
######## t/ddl_innodb.test ######
|
||||||
#
|
#
|
||||||
# Stress the storage engine InnoDB with CREATE/DROP TABLE/INDEX
|
# Stress the storage engine InnoDB with CREATE/DROP TABLE/INDEX
|
||||||
@@ -34,6 +35,13 @@ if (!$run)
|
|||||||
##### Some preparations needed for the ddl*.inc scripts
|
##### Some preparations needed for the ddl*.inc scripts
|
||||||
--source suite/stress/include/ddl.pre
|
--source suite/stress/include/ddl.pre
|
||||||
|
|
||||||
|
if ($have_debug) {
|
||||||
|
--disable_query_log
|
||||||
|
SET @old_debug_dbug = @@global.debug_dbug;
|
||||||
|
SET DEBUG_DBUG="+d,ib_buf_create_intermittent_wait";
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
--source suite/stress/include/ddl1.inc
|
--source suite/stress/include/ddl1.inc
|
||||||
--source suite/stress/include/ddl2.inc
|
--source suite/stress/include/ddl2.inc
|
||||||
--source suite/stress/include/ddl3.inc
|
--source suite/stress/include/ddl3.inc
|
||||||
@@ -43,5 +51,11 @@ if (!$run)
|
|||||||
--source suite/stress/include/ddl7.inc
|
--source suite/stress/include/ddl7.inc
|
||||||
--source suite/stress/include/ddl8.inc
|
--source suite/stress/include/ddl8.inc
|
||||||
|
|
||||||
|
if ($have_debug) {
|
||||||
|
--disable_query_log
|
||||||
|
SET @@global.debug_dbug = @old_debug_dbug;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
##### Cleanup
|
##### Cleanup
|
||||||
--source suite/stress/include/ddl.cln
|
--source suite/stress/include/ddl.cln
|
||||||
|
@@ -3289,22 +3289,47 @@ retry:
|
|||||||
|
|
||||||
if (!mtr->have_x_latch(reinterpret_cast<const buf_block_t&>(*bpage)))
|
if (!mtr->have_x_latch(reinterpret_cast<const buf_block_t&>(*bpage)))
|
||||||
{
|
{
|
||||||
const bool got= bpage->lock.x_lock_try();
|
/* Buffer-fix the block to prevent the block being concurrently freed
|
||||||
if (!got)
|
after we release the buffer pool mutex. It should work fine with
|
||||||
|
concurrent load of the page (free on disk) to buffer pool due to
|
||||||
|
possible read ahead. After we find a zero filled page during load, we
|
||||||
|
call buf_pool_t::corrupted_evict, where we try to wait for all buffer
|
||||||
|
fixes to go away only after resetting the page ID and releasing the
|
||||||
|
page latch. */
|
||||||
|
auto state= bpage->fix();
|
||||||
|
DBUG_EXECUTE_IF("ib_buf_create_intermittent_wait",
|
||||||
{
|
{
|
||||||
|
static bool need_to_wait = false;
|
||||||
|
need_to_wait = !need_to_wait;
|
||||||
|
/* Simulate try lock failure in every alternate call. */
|
||||||
|
if (need_to_wait) {
|
||||||
|
goto must_wait;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bpage->lock.x_lock_try())
|
||||||
|
{
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
must_wait:
|
||||||
|
#endif
|
||||||
mysql_mutex_unlock(&buf_pool.mutex);
|
mysql_mutex_unlock(&buf_pool.mutex);
|
||||||
|
|
||||||
bpage->lock.x_lock();
|
bpage->lock.x_lock();
|
||||||
const page_id_t id{bpage->id()};
|
const page_id_t id{bpage->id()};
|
||||||
if (UNIV_UNLIKELY(id != page_id))
|
if (UNIV_UNLIKELY(id != page_id))
|
||||||
{
|
{
|
||||||
ut_ad(id.is_corrupted());
|
ut_ad(id.is_corrupted());
|
||||||
|
ut_ad(bpage->is_freed());
|
||||||
|
bpage->unfix();
|
||||||
bpage->lock.x_unlock();
|
bpage->lock.x_unlock();
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
mysql_mutex_lock(&buf_pool.mutex);
|
mysql_mutex_lock(&buf_pool.mutex);
|
||||||
|
state= bpage->state();
|
||||||
|
ut_ad(!bpage->is_io_fixed(state));
|
||||||
|
ut_ad(bpage->buf_fix_count(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto state= bpage->fix();
|
|
||||||
ut_ad(state >= buf_page_t::FREED);
|
ut_ad(state >= buf_page_t::FREED);
|
||||||
ut_ad(state < buf_page_t::READ_FIX);
|
ut_ad(state < buf_page_t::READ_FIX);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user