Commit 489b5569 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-30422 Merge new release of InnoDB 5.7.41 to 10.3

MySQL 5.7.41 includes one InnoDB change
mysql/mysql-server@d2d6b2dd00f709bc528386009150d4bc726e25a0
that seems to be applicable to MariaDB Server 10.3 and 10.4.
Even though commit 5b9ee8d8
seems to have fixed sporadic failures on our CI systems, it is
theoretically possible that another race condition remained.

buf_flush_page_cleaner_coordinator(): In the final loop,
wait also for buf_get_n_pending_read_ios() to reach 0.
In this way, if a secondary index leaf page was read into the
buffer pool and ibuf_merge_or_delete_for_page() modified that
page or some change buffer pages, the flush loop would execute
until the buffer pool really is in a clean state.

This potential data corruption bug does not affect MariaDB Server 10.5
or later, thanks to commit b42294bc
which removed change buffer merges that are not explicitly requested.
parent 834650c7
...@@ -3324,20 +3324,27 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*) ...@@ -3324,20 +3324,27 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
bool success; bool success;
do { do {
/* In case an asynchronous read request was posted by
any thread (other than something invoking
ibuf_merge_in_background()), it is possible that the
change buffer will be merged to the page once the read
completes. To avoid race conditions and corruption due
to that, we will loop here until there are no pending
page read operations. */
success = !buf_get_n_pending_read_ios();
pc_request(ULINT_MAX, LSN_MAX); pc_request(ULINT_MAX, LSN_MAX);
while (pc_flush_slot() > 0) {} while (pc_flush_slot() > 0) {}
ulint n_flushed_lru = 0; ulint n_flushed_lru = 0;
ulint n_flushed_list = 0; ulint n_flushed_list = 0;
success = pc_wait_finished(&n_flushed_lru, &n_flushed_list); success = pc_wait_finished(&n_flushed_lru, &n_flushed_list)
&& success && !n_flushed_lru && !n_flushed_list;
n_flushed = n_flushed_lru + n_flushed_list;
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
buf_flush_wait_LRU_batch_end(); buf_flush_wait_LRU_batch_end();
} while (!success || n_flushed > 0); } while (!success);
/* Some sanity checks */ /* Some sanity checks */
ut_a(srv_get_active_thread_type() == SRV_NONE); ut_a(srv_get_active_thread_type() == SRV_NONE);
......
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