Commit 5b53342a authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-32588 InnoDB may hang when running out of buffer pool

buf_flush_LRU_list_batch(): Do not skip pages that are actually clean
but in buf_pool.flush_list due to the "lazy removal" optimization of
commit 22b62eda, but try to evict them.
After acquiring buf_pool.flush_list_mutex, reread oldest_modification
to ensure that the block still remains in buf_pool.flush_list.

In addition to server hangs, this bug could also cause
InnoDB: Failing assertion: list.count > 0
in invocations of UT_LIST_REMOVE(flush_list, ...).

This fixes a regression that was caused by
commit a55b951e
and possibly made more likely to hit due to
commit aa719b50.
parent 39e3ca8b
......@@ -1304,16 +1304,14 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict,
ut_ad(state >= buf_page_t::FREED);
ut_ad(bpage->in_LRU_list);
switch (bpage->oldest_modification()) {
case 0:
if (!bpage->oldest_modification())
{
evict:
if (state != buf_page_t::FREED &&
(state >= buf_page_t::READ_FIX || (~buf_page_t::LRU_MASK & state)))
continue;
buf_LRU_free_page(bpage, true);
++n->evicted;
/* fall through */
case 1:
if (UNIV_LIKELY(scanned & 31))
continue;
mysql_mutex_unlock(&buf_pool.mutex);
......@@ -1329,7 +1327,11 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict,
switch (bpage->oldest_modification()) {
case 1:
mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_pool.delete_from_flush_list(bpage);
if (ut_d(lsn_t lsn=) bpage->oldest_modification())
{
ut_ad(lsn == 1); /* It must be clean while we hold bpage->lock */
buf_pool.delete_from_flush_list(bpage);
}
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
/* fall through */
case 0:
......
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