From ac3e7f788eced87ea4780584d65f815020f9b31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 24 Jan 2018 10:23:52 +0200 Subject: MDEV-15016: multiple page cleaner threads use a lot of CPU While the bug was reported as a regression of MDEV-11025 Make number of page cleaner threads variable dynamic in MariaDB Server 10.3, the code that MariaDB Server 10.2 inherited from MySQL 5.7.4 (WL#6642) looks prone to similar errors. pc_flush_slot(): If there is no work to do, reset the is_requested signal, to avoid potential busy-waiting in buf_flush_page_cleaner_worker(). If the coordinator thread has shut down, avoid resetting the is_requested event, to avoid a potential hang at shutdown if there are multiple worker threads. --- storage/innobase/buf/buf0flu.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 9426d140e71..9807a9696e9 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. Copyright (c) 2013, 2014, Fusion-io This program is free software; you can redistribute it and/or modify it under @@ -2843,7 +2843,9 @@ pc_flush_slot(void) mutex_enter(&page_cleaner->mutex); - if (page_cleaner->n_slots_requested > 0) { + if (!page_cleaner->n_slots_requested) { + os_event_reset(page_cleaner->is_requested); + } else { page_cleaner_slot_t* slot = NULL; ulint i; @@ -2865,16 +2867,16 @@ pc_flush_slot(void) page_cleaner->n_slots_flushing++; slot->state = PAGE_CLEANER_STATE_FLUSHING; - if (page_cleaner->n_slots_requested == 0) { - os_event_reset(page_cleaner->is_requested); - } - - if (!page_cleaner->is_running) { + if (UNIV_UNLIKELY(!page_cleaner->is_running)) { slot->n_flushed_lru = 0; slot->n_flushed_list = 0; goto finish_mutex; } + if (page_cleaner->n_slots_requested == 0) { + os_event_reset(page_cleaner->is_requested); + } + mutex_exit(&page_cleaner->mutex); lru_tm = ut_time_ms(); @@ -2885,7 +2887,7 @@ pc_flush_slot(void) lru_tm = ut_time_ms() - lru_tm; lru_pass++; - if (!page_cleaner->is_running) { + if (UNIV_UNLIKELY(!page_cleaner->is_running)) { slot->n_flushed_list = 0; goto finish; } -- cgit v1.2.1