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 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
...@@ -104,6 +104,14 @@ class rw_lock ...@@ -104,6 +104,14 @@ class rw_lock
DBUG_ASSERT((l & ~WRITER_WAITING) == UPDATER); DBUG_ASSERT((l & ~WRITER_WAITING) == UPDATER);
return true; 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. /** Wait for an exclusive lock.
@return whether the exclusive lock was acquired */ @return whether the exclusive lock was acquired */
bool write_lock_poll() bool write_lock_poll()
......
...@@ -93,6 +93,7 @@ class ssux_lock_low final : private rw_lock ...@@ -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); } void u_lock() { uint32_t l; if (!update_trylock(l)) update_lock(l); }
bool u_lock_try() { uint32_t l; return update_trylock(l); } bool u_lock_try() { uint32_t l; return update_trylock(l); }
void u_wr_upgrade() { if (!upgrade_trylock()) write_lock(true); } 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 wr_lock() { if (!write_trylock()) write_lock(false); }
void rd_unlock(); void rd_unlock();
void u_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 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
...@@ -193,6 +193,14 @@ class sux_lock final ...@@ -193,6 +193,14 @@ class sux_lock final
/** Upgrade an update lock */ /** Upgrade an update lock */
inline void u_x_upgrade(); inline void u_x_upgrade();
inline void u_x_upgrade(const char *file, unsigned line); 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 /** Acquire an exclusive lock or upgrade an update lock
@return whether U locks were upgraded to X */ @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) ...@@ -988,13 +988,11 @@ static void mtr_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type)
block->lock.s_lock(); block->lock.s_lock();
break; break;
case MTR_MEMO_PAGE_SX_FIX: case MTR_MEMO_PAGE_SX_FIX:
block->lock.u_unlock(); block->lock.u_x_upgrade();
block->lock.x_lock();
if (dict_index_t *index= block->index) if (dict_index_t *index= block->index)
if (index->freed()) if (index->freed())
btr_search_drop_page_hash_index(block); btr_search_drop_page_hash_index(block);
block->lock.u_lock(); block->lock.x_u_downgrade();
block->lock.x_unlock();
break; break;
default: default:
ut_ad(fix_type == MTR_MEMO_PAGE_X_FIX); 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