mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02: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:
parent
80fff4c6b1
commit
35d477dd1d
2 changed files with 42 additions and 3 deletions
|
|
@ -3289,22 +3289,47 @@ retry:
|
|||
|
||||
if (!mtr->have_x_latch(reinterpret_cast<const buf_block_t&>(*bpage)))
|
||||
{
|
||||
const bool got= bpage->lock.x_lock_try();
|
||||
if (!got)
|
||||
/* Buffer-fix the block to prevent the block being concurrently freed
|
||||
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);
|
||||
|
||||
bpage->lock.x_lock();
|
||||
const page_id_t id{bpage->id()};
|
||||
if (UNIV_UNLIKELY(id != page_id))
|
||||
{
|
||||
ut_ad(id.is_corrupted());
|
||||
ut_ad(bpage->is_freed());
|
||||
bpage->unfix();
|
||||
bpage->lock.x_unlock();
|
||||
goto retry;
|
||||
}
|
||||
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::READ_FIX);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue