Skip to content

Commit a1542f8

Browse files
committed
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 03ca649 (MDEV-24142).
1 parent 26d6224 commit a1542f8

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

storage/innobase/include/rw_lock.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 2020, MariaDB Corporation.
3+
Copyright (c) 2020, 2021, MariaDB Corporation.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -104,6 +104,14 @@ class rw_lock
104104
DBUG_ASSERT((l & ~WRITER_WAITING) == UPDATER);
105105
return true;
106106
}
107+
/** Downgrade an exclusive lock to an update lock. */
108+
void downgrade()
109+
{
110+
IF_DBUG_ASSERT(auto l=,)
111+
lock.fetch_xor(WRITER | UPDATER, std::memory_order_relaxed);
112+
DBUG_ASSERT((l & ~WRITER_WAITING) == WRITER);
113+
}
114+
107115
/** Wait for an exclusive lock.
108116
@return whether the exclusive lock was acquired */
109117
bool write_lock_poll()

storage/innobase/include/srw_lock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class ssux_lock_low final : private rw_lock
9393
void u_lock() { uint32_t l; if (!update_trylock(l)) update_lock(l); }
9494
bool u_lock_try() { uint32_t l; return update_trylock(l); }
9595
void u_wr_upgrade() { if (!upgrade_trylock()) write_lock(true); }
96+
void wr_u_downgrade() { downgrade(); }
9697
void wr_lock() { if (!write_trylock()) write_lock(false); }
9798
void rd_unlock();
9899
void u_unlock();

storage/innobase/include/sux_lock.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 2020, MariaDB Corporation.
3+
Copyright (c) 2020, 2021, MariaDB Corporation.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -193,6 +193,14 @@ class sux_lock final
193193
/** Upgrade an update lock */
194194
inline void u_x_upgrade();
195195
inline void u_x_upgrade(const char *file, unsigned line);
196+
/** Downgrade a single exclusive lock to an update lock */
197+
void x_u_downgrade()
198+
{
199+
ut_ad(have_u_or_x());
200+
ut_ad(recursive <= RECURSIVE_MAX);
201+
recursive*= RECURSIVE_U;
202+
lock.wr_u_downgrade();
203+
}
196204

197205
/** Acquire an exclusive lock or upgrade an update lock
198206
@return whether U locks were upgraded to X */

storage/innobase/mtr/mtr0mtr.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -988,13 +988,11 @@ static void mtr_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type)
988988
block->lock.s_lock();
989989
break;
990990
case MTR_MEMO_PAGE_SX_FIX:
991-
block->lock.u_unlock();
992-
block->lock.x_lock();
991+
block->lock.u_x_upgrade();
993992
if (dict_index_t *index= block->index)
994993
if (index->freed())
995994
btr_search_drop_page_hash_index(block);
996-
block->lock.u_lock();
997-
block->lock.x_unlock();
995+
block->lock.x_u_downgrade();
998996
break;
999997
default:
1000998
ut_ad(fix_type == MTR_MEMO_PAGE_X_FIX);

0 commit comments

Comments
 (0)