From 147a317e81ca8b132c353e0309db96d7e74637ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 31 Mar 2021 14:11:56 +0300 Subject: MDEV-25072: Livelock due to innodb_change_buffering_debug buf_page_get_low(): Do not try to re-evict the page if it is multiply buffer-fixed. In commit 7cffb5f6e8a231a041152447be8980ce35d2c9b8 (MDEV-23399) a livelock was introduced. If multiple threads are concurrently requesting the same secondary index leaf page in buf_page_get_low() and innodb_change_buffering_debug is set, all threads would try to evict the page in a busy loop, never succeeding because the block is buffer-fixed by other threads. Thanks to Roel Van de Paar for reporting the original failure and Elena Stepanova for producing an "rr replay" trace. --- storage/innobase/buf/buf0buf.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 2f40ea28e0c..2923c6d4790 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3324,7 +3324,8 @@ re_evict: buf_flush_lists(ULINT_UNDEFINED, LSN_MAX); buf_flush_wait_batch_end_acquiring_mutex(false); - if (!fix_block->page.oldest_modification()) { + if (fix_block->page.buf_fix_count() == 1 + && !fix_block->page.oldest_modification()) { goto re_evict; } -- cgit v1.2.1