From 2bcf8d793a88bd69d7dabadefb2269e4b6f2aaca Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 11 Nov 2021 15:22:20 +0600 Subject: MDEV-27022 slightly optimize crash recovery in InnoDB recv_sys_t::apply(): don't write to dist and fsync() the last batch. Insead, sort it by oldest_modification for MariaDB server and some mariabackup operations. log_sort_flush_list(): a thread-safe function which sorts buf_pool::flush_list --- storage/innobase/log/log0recv.cc | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index ad2078aba88..b910f9075e3 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3059,6 +3059,32 @@ inline fil_space_t *fil_system_t::find(const char *path) const return nullptr; } +/** Thread-safe function which sorts flush_list by oldest_modification */ +static void log_sort_flush_list() +{ + mysql_mutex_lock(&buf_pool.flush_list_mutex); + + const size_t size= UT_LIST_GET_LEN(buf_pool.flush_list); + std::unique_ptr list(new buf_page_t *[size]); + + size_t idx= 0; + for (buf_page_t *p= UT_LIST_GET_FIRST(buf_pool.flush_list); p; + p= UT_LIST_GET_NEXT(list, p)) + list.get()[idx++]= p; + + std::sort(list.get(), list.get() + size, + [](const buf_page_t *lhs, const buf_page_t *rhs) { + return rhs->oldest_modification() < lhs->oldest_modification(); + }); + + UT_LIST_INIT(buf_pool.flush_list, &buf_page_t::list); + + for (size_t i= 0; i < size; i++) + UT_LIST_ADD_LAST(buf_pool.flush_list, list[i]); + + mysql_mutex_unlock(&buf_pool.flush_list_mutex); +} + /** Apply buffered log to persistent data pages. @param last_batch whether it is possible to write more redo log */ void recv_sys_t::apply(bool last_batch) @@ -3254,9 +3280,15 @@ next_page: mysql_mutex_assert_not_owner(&log_sys.mutex); mysql_mutex_unlock(&mutex); - /* Instead of flushing, last_batch could sort the buf_pool.flush_list - in ascending order of buf_page_t::oldest_modification. */ - buf_flush_sync_batch(recovered_lsn); + if (last_batch && srv_operation != SRV_OPERATION_RESTORE && + srv_operation != SRV_OPERATION_RESTORE_EXPORT) + log_sort_flush_list(); + else + { + /* Instead of flushing, last_batch could sort the buf_pool.flush_list + in ascending order of buf_page_t::oldest_modification. */ + buf_flush_sync_batch(recovered_lsn); + } if (!last_batch) { -- cgit v1.2.1