Skip to content

Commit 5e93fe1

Browse files
committed
MDEV-37677: Inconsistent flush_list after InnoDB recovery
In commit bea4adc (MDEV-35225) we inadvertently introduced a race condition. Another thread may invoke buf_page_t::write_complete() between the time log_sort_flush_list() inserted the block to the list for sorting, and the time it would apply the sorted list back to buf_pool.flush_list. In this case, log_sort_flush_list() would neither add the block to buf_pool.flush_list nor clear the buf_page_t::oldest_modification_ so that it would correctly indicate whether the block is in the list. log_sort_flush_list(): Simplify the logic, and always add the entire sorted list to the buf_pool.flush_list, even if they had been written back during the time we were copying or sorting. This fixes an anomaly where a subsequent buf_pool_t::insert_into_flush_list() would end up incrementing buf_pool.flush_list.count by one too much. Thanks to Daniel Black for providing an "rr replay" trace of a failure.
1 parent 9f92d64 commit 5e93fe1

File tree

1 file changed

+2
-4
lines changed

1 file changed

+2
-4
lines changed

storage/innobase/log/log0recv.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3667,10 +3667,8 @@ static void log_sort_flush_list() noexcept
36673667
for (size_t i= 0; i < idx; i++)
36683668
{
36693669
buf_page_t *b= list[i];
3670-
const lsn_t lsn{b->oldest_modification()};
3671-
if (lsn == 1)
3672-
continue;
3673-
DBUG_ASSERT(lsn > 2);
3670+
ut_d(const lsn_t lsn{b->oldest_modification()});
3671+
ut_ad(lsn == 1 || lsn > 2);
36743672
UT_LIST_ADD_LAST(buf_pool.flush_list, b);
36753673
}
36763674

0 commit comments

Comments
 (0)