summaryrefslogtreecommitdiff
path: root/storage/innobase/buf
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-11-13 20:12:29 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-11-13 20:16:39 +0200
commitbb328a2a274b0b5cc024f298fcac70b3f0fb75aa (patch)
treecfce8af41648225f8a6a0ac344b75f3bb4c8b3ed /storage/innobase/buf
parent190e8a4c2aeb417b405756b193e135c542d46b34 (diff)
downloadmariadb-git-bb328a2a274b0b5cc024f298fcac70b3f0fb75aa.tar.gz
MDEV-24188 Hang in buf_page_create() after reusing a previously freed page
The fix of MDEV-23456 (commit b1009ae5c16697d5eef443cc6a60a74301148c73) introduced a livelock between page flushing and a thread that is executing buf_page_create(). buf_page_create(): If the current mini-transaction is holding an exclusive latch on the page, do not attempt to acquire another one, and do not care about any I/O fix. mtr_t::have_x_latch(): Replaces mtr_t::get_fix_count(). dyn_buf_t::for_each_block(const Functor&) const: A new variant. rw_lock_own(): Add a const qualifier. Reviewed by: Thirunarayanan Balathandayuthapani
Diffstat (limited to 'storage/innobase/buf')
-rw-r--r--storage/innobase/buf/buf0buf.cc52
1 files changed, 27 insertions, 25 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index a54d98adee0..9f3d743ada1 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -5511,6 +5511,7 @@ loop:
&& !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
ut_d(block->page.file_page_was_freed = FALSE);
buf_page_state page_state = buf_block_get_state(block);
+ bool have_x_latch = false;
#ifdef BTR_CUR_HASH_ADAPT
const dict_index_t *drop_hash_entry= NULL;
#endif
@@ -5563,26 +5564,26 @@ loop:
free_block = NULL;
break;
case BUF_BLOCK_FILE_PAGE:
- buf_block_fix(block);
- const int32_t num_fix_count =
- mtr->get_fix_count(block) + 1;
- buf_page_mutex_enter(block);
- while (buf_block_get_io_fix(block) != BUF_IO_NONE
- || (num_fix_count
- != block->page.buf_fix_count)) {
- buf_page_mutex_exit(block);
- buf_pool_mutex_exit(buf_pool);
- rw_lock_x_unlock(hash_lock);
-
- os_thread_yield();
-
- buf_pool_mutex_enter(buf_pool);
- rw_lock_x_lock(hash_lock);
+ have_x_latch = mtr->have_x_latch(*block);
+ if (!have_x_latch) {
+ buf_block_fix(block);
buf_page_mutex_enter(block);
+ while (buf_block_get_io_fix(block)
+ != BUF_IO_NONE
+ || block->page.buf_fix_count != 1) {
+ buf_page_mutex_exit(block);
+ buf_pool_mutex_exit(buf_pool);
+ rw_lock_x_unlock(hash_lock);
+
+ os_thread_sleep(1000);
+
+ buf_pool_mutex_enter(buf_pool);
+ rw_lock_x_lock(hash_lock);
+ buf_page_mutex_enter(block);
+ }
+ rw_lock_x_lock(&block->lock);
+ buf_page_mutex_exit(block);
}
-
- rw_lock_x_lock(&block->lock);
- buf_page_mutex_exit(block);
#ifdef BTR_CUR_HASH_ADAPT
drop_hash_entry = block->index;
#endif
@@ -5601,16 +5602,17 @@ loop:
}
#endif /* BTR_CUR_HASH_ADAPT */
+ if (!have_x_latch) {
#ifdef UNIV_DEBUG
- if (!fsp_is_system_temporary(page_id.space())) {
- rw_lock_s_lock_nowait(
- &block->debug_latch,
- __FILE__, __LINE__);
- }
+ if (!fsp_is_system_temporary(page_id.space())) {
+ rw_lock_s_lock_nowait(
+ &block->debug_latch,
+ __FILE__, __LINE__);
+ }
#endif /* UNIV_DEBUG */
- mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
-
+ mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
+ }
return block;
}