summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-04 17:52:23 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-04 17:52:23 +0200
commit83591a23d6c2a09d9c24cccbc7d6e20a6feffe86 (patch)
tree28c4d10b611ed53ef651630aecc2eba707a3c8a7
parentaa0e3805681552cff5dced141f695c96a4da872f (diff)
downloadmariadb-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.cc15
-rw-r--r--storage/innobase/include/buf0dblwr.h20
-rw-r--r--storage/innobase/include/srv0srv.h7
-rw-r--r--storage/innobase/srv/srv0mon.cc8
-rw-r--r--storage/innobase/srv/srv0srv.cc17
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;