diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-12-04 17:52:23 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-12-04 17:52:23 +0200 |
commit | 83591a23d6c2a09d9c24cccbc7d6e20a6feffe86 (patch) | |
tree | 28c4d10b611ed53ef651630aecc2eba707a3c8a7 | |
parent | aa0e3805681552cff5dced141f695c96a4da872f (diff) | |
download | mariadb-git-bb-10.5-MDEV-24350.tar.gz |
MDEV-24350 buf_dblwr unnecessarily uses memory-intensive srv_stats countersbb-10.5-MDEV-24350
The counters in srv_stats use std::atomic and multiple cache lines per
counter. This is an overkill in a case where a critical section already
exists in the code. A regular variable will work just fine, with much
smaller memory bus impact.
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 15 | ||||
-rw-r--r-- | storage/innobase/include/buf0dblwr.h | 20 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 7 | ||||
-rw-r--r-- | storage/innobase/srv/srv0mon.cc | 8 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 17 |
5 files changed, 45 insertions, 22 deletions
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index f17cf6cc128..4e33bc58b53 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -583,6 +583,7 @@ bool buf_dblwr_t::flush_buffered_writes(const ulint size) const bool multi_batch= block1 + static_cast<uint32_t>(size) != block2 && old_first_free > size; flushing_buffered_writes= 1 + multi_batch; + pages_submitted+= old_first_free; /* Now safe to release the mutex. */ mysql_mutex_unlock(&mutex); #ifdef UNIV_DEBUG @@ -617,7 +618,6 @@ bool buf_dblwr_t::flush_buffered_writes(const ulint size) os_aio(request, write_buf, os_offset_t{block1.page_no()} << srv_page_size_shift, old_first_free << srv_page_size_shift); - srv_stats.data_written.add(old_first_free); return true; } @@ -634,17 +634,18 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) ut_ad(batch_running); ut_ad(flushing_buffered_writes); ut_ad(flushing_buffered_writes <= 2); - const bool completed= !--flushing_buffered_writes; - mysql_mutex_unlock(&mutex); - - if (!completed) + writes_completed++; + if (UNIV_UNLIKELY(--flushing_buffered_writes)) + { + mysql_mutex_unlock(&mutex); return; + } slot *const flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0]; ut_ad(flush_slot->reserved == flush_slot->first_free); /* increment the doublewrite flushed pages counter */ - srv_stats.dblwr_pages_written.add(flush_slot->first_free); - srv_stats.dblwr_writes.inc(); + pages_written+= flush_slot->first_free; + mysql_mutex_unlock(&mutex); /* Now flush the doublewrite buffer data to disk */ fil_system.sys_space->flush(); diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index 47517adc40b..e95f2844fdc 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -66,6 +66,12 @@ class buf_dblwr_t bool batch_running; /** number of expected flush_buffered_writes_completed() calls */ unsigned flushing_buffered_writes; + /** pages submitted to flush_buffered_writes() */ + ulint pages_submitted; + /** number of flush_buffered_writes_completed() calls */ + ulint writes_completed; + /** number of pages written by flush_buffered_writes_completed() */ + ulint pages_written; slot slots[2]; slot *active_slot= &slots[0]; @@ -84,6 +90,20 @@ public: /** Free the doublewrite buffer. */ void close(); + /** Acquire the mutex */ + void lock() { mysql_mutex_lock(&mutex); } + /** @return the number of submitted page writes */ + ulint submitted() const + { mysql_mutex_assert_owner(&mutex); return pages_submitted; } + /** @return the number of completed batches */ + ulint batches() const + { mysql_mutex_assert_owner(&mutex); return writes_completed; } + /** @return the number of final pages written */ + ulint written() const + { mysql_mutex_assert_owner(&mutex); return pages_written; } + /** Release the mutex */ + void unlock() { mysql_mutex_unlock(&mutex); } + /** Initialize the doublewrite buffer memory structure on recovery. If we are upgrading from a version before MySQL 4.1, then this function performs the necessary update operations to support diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 4fe90e8a0dc..7b65000c115 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -81,13 +81,6 @@ struct srv_stats_t space in the log buffer and have to flush it */ ulint_ctr_1_t log_waits; - /** Count the number of times the doublewrite buffer was flushed */ - ulint_ctr_1_t dblwr_writes; - - /** Store the number of pages that have been flushed to the - doublewrite buffer */ - ulint_ctr_1_t dblwr_pages_written; - #if defined(LINUX_NATIVE_AIO) ulint_ctr_1_t buffered_aio_submitted; #endif diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 174355f992a..c98be4dc682 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -1720,12 +1720,16 @@ srv_mon_process_existing_counter( /* innodb_dblwr_writes */ case MONITOR_OVLD_SRV_DBLWR_WRITES: - value = srv_stats.dblwr_writes; + buf_dblwr.lock(); + value = buf_dblwr.batches(); + buf_dblwr.unlock(); break; /* innodb_dblwr_pages_written */ case MONITOR_OVLD_SRV_DBLWR_PAGES_WRITTEN: - value = srv_stats.dblwr_pages_written; + buf_dblwr.lock(); + value = buf_dblwr.written(); + buf_dblwr.unlock(); break; /* innodb_page_size */ diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index f62dfd87671..71ae6e04881 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1093,7 +1093,17 @@ srv_export_innodb_status(void) export_vars.innodb_data_writes = os_n_file_writes; - export_vars.innodb_data_written = srv_stats.data_written; + ulint dblwr = 0; + + if (buf_dblwr.is_initialised()) { + buf_dblwr.lock(); + dblwr = buf_dblwr.submitted(); + export_vars.innodb_dblwr_pages_written = buf_dblwr.written(); + export_vars.innodb_dblwr_writes = buf_dblwr.batches(); + buf_dblwr.unlock(); + } + + export_vars.innodb_data_written = srv_stats.data_written + dblwr; export_vars.innodb_buffer_pool_read_requests = buf_pool.stat.n_page_gets; @@ -1169,11 +1179,6 @@ srv_export_innodb_status(void) export_vars.innodb_log_writes = srv_stats.log_writes; - export_vars.innodb_dblwr_pages_written = - srv_stats.dblwr_pages_written; - - export_vars.innodb_dblwr_writes = srv_stats.dblwr_writes; - export_vars.innodb_pages_created = buf_pool.stat.n_pages_created; export_vars.innodb_pages_read = buf_pool.stat.n_pages_read; |