Commit a1542f8a authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24643: Assertion failed in rw_lock::update_unlock()

mtr_defer_drop_ahi(): Upgrade the U lock to X lock and downgrade
it back to U lock in case the adaptive hash index needs to be dropped.

This regression was introduced in
commit 03ca6495 (MDEV-24142).
parent 26d6224d
/*****************************************************************************
Copyright (c) 2020, MariaDB Corporation.
Copyright (c) 2020, 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
......@@ -104,6 +104,14 @@ class rw_lock
DBUG_ASSERT((l & ~WRITER_WAITING) == UPDATER);
return true;
}
/** Downgrade an exclusive lock to an update lock. */
void downgrade()
{
IF_DBUG_ASSERT(auto l=,)
lock.fetch_xor(WRITER | UPDATER, std::memory_order_relaxed);
DBUG_ASSERT((l & ~WRITER_WAITING) == WRITER);
}
/** Wait for an exclusive lock.
@return whether the exclusive lock was acquired */
bool write_lock_poll()
......
......@@ -93,6 +93,7 @@ class ssux_lock_low final : private rw_lock
void u_lock() { uint32_t l; if (!update_trylock(l)) update_lock(l); }
bool u_lock_try() { uint32_t l; return update_trylock(l); }
void u_wr_upgrade() { if (!upgrade_trylock()) write_lock(true); }
void wr_u_downgrade() { downgrade(); }
void wr_lock() { if (!write_trylock()) write_lock(false); }
void rd_unlock();
void u_unlock();
......
/*****************************************************************************
Copyright (c) 2020, MariaDB Corporation.
Copyright (c) 2020, 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
......@@ -193,6 +193,14 @@ class sux_lock final
/** Upgrade an update lock */
inline void u_x_upgrade();
inline void u_x_upgrade(const char *file, unsigned line);
/** Downgrade a single exclusive lock to an update lock */
void x_u_downgrade()
{
ut_ad(have_u_or_x());
ut_ad(recursive <= RECURSIVE_MAX);
recursive*= RECURSIVE_U;
lock.wr_u_downgrade();
}
/** Acquire an exclusive lock or upgrade an update lock
@return whether U locks were upgraded to X */
......
......@@ -988,13 +988,11 @@ static void mtr_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type)
block->lock.s_lock();
break;
case MTR_MEMO_PAGE_SX_FIX:
block->lock.u_unlock();
block->lock.x_lock();
block->lock.u_x_upgrade();
if (dict_index_t *index= block->index)
if (index->freed())
btr_search_drop_page_hash_index(block);
block->lock.u_lock();
block->lock.x_unlock();
block->lock.x_u_downgrade();
break;
default:
ut_ad(fix_type == MTR_MEMO_PAGE_X_FIX);
......
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