From 41c699dc128dbed9983810f6b9a1318beccbd35e Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sun, 27 May 2018 14:45:33 +0300 Subject: [PATCH] Bug #79455: Restore get_sched_indexer_t This partially reverts the fix for bug bug#20709391 "SCHED_GETCPU() IN DEFAULT GET_RND_INDEX() COULD NOT GENERATE RANDOM COUNTERS" by re-introducing get_sched_indexer_t on Linux and Windows and using it (if available) as the default indexer in ib_counter_t. It also changes InnoDB row counter updates to use the default indexer rather than override it with MySQL trx ID. In sync_array_get() use the counter_indexer_t explicitly, because other ones are not random enough per comments in the fix for bug #20709391. This in itself does not introduce any measurable performance improvements, but is rather a groundwork for further changes. --- storage/innobase/handler/ha_innodb.cc | 5 ++--- storage/innobase/include/os0numa.h | 2 +- storage/innobase/include/sync0arr.ic | 2 +- storage/innobase/include/ut0counter.h | 28 ++++++++++++++++++++++++++++ storage/innobase/row/row0mysql.cc | 4 ++-- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index fed9254f104..93ce5c7ac00 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8645,8 +8645,7 @@ int ha_innobase::index_read( switch (ret) { case DB_SUCCESS: error = 0; - srv_stats.n_rows_read.add(thd_get_thread_id(m_prebuilt->trx->mysql_thd), - 1); + srv_stats.n_rows_read.inc(); break; case DB_RECORD_NOT_FOUND: @@ -8887,7 +8886,7 @@ int ha_innobase::general_fetch( switch (ret) { case DB_SUCCESS: error = 0; - srv_stats.n_rows_read.add(thd_get_thread_id(trx->mysql_thd), 1); + srv_stats.n_rows_read.inc(); break; case DB_RECORD_NOT_FOUND: error = HA_ERR_END_OF_FILE; diff --git a/storage/innobase/include/os0numa.h b/storage/innobase/include/os0numa.h index 79e705c07b8..f64770675a3 100644 --- a/storage/innobase/include/os0numa.h +++ b/storage/innobase/include/os0numa.h @@ -48,7 +48,7 @@ this program; if not, write to the Free Software Foundation, Inc., #endif /* HAVE_LIBNUMA */ #ifdef HAVE_SCHED_GETCPU -#include +#include #endif /* HAVE_SCHED_GETCPU */ #ifdef _WIN32 diff --git a/storage/innobase/include/sync0arr.ic b/storage/innobase/include/sync0arr.ic index 4b5834e7f66..0f1ded1fd3e 100644 --- a/storage/innobase/include/sync0arr.ic +++ b/storage/innobase/include/sync0arr.ic @@ -47,7 +47,7 @@ sync_array_t *sync_array_get() { } return ( - sync_wait_array[default_indexer_t<>::get_rnd_index() % sync_array_size]); + sync_wait_array[counter_indexer_t<>::get_rnd_index() % sync_array_size]); } /** Get an instance of the sync wait array and reserve a wait array cell diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h index daeb1c16cc2..52fad0f040b 100644 --- a/storage/innobase/include/ut0counter.h +++ b/storage/innobase/include/ut0counter.h @@ -38,6 +38,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include "univ.i" +#include "os0numa.h" #include "os0thread.h" #include "ut0dbg.h" @@ -62,6 +63,29 @@ struct generic_indexer_t { } }; +#ifdef HAVE_OS_GETCPU +/** Use the cpu id to index into the counter array. If it fails then +use the thread id. */ +template +struct get_sched_indexer_t : public generic_indexer_t { + /** Default constructor/destructor should be OK. */ + + enum { fast = 1 }; + + /* @return result from sched_getcpu(), use thread id if it fails. */ + static size_t get_rnd_index() UNIV_NOTHROW { + + int cpu = os_getcpu(); + + if (unlikely(cpu < 0)) { + return static_cast(os_thread_get_curr_id()); + } + + return(static_cast(cpu)); + } +}; +#endif + /** Use the result of my_timer_cycles(), which mainly uses RDTSC for cycles, to index into the counter array. See the comments for my_timer_cycles() */ template @@ -111,7 +135,11 @@ struct single_indexer_t { } }; +#ifdef HAVE_OS_GETCPU +#define default_indexer_t get_sched_indexer_t +#else #define default_indexer_t counter_indexer_t +#endif /** Class for using fuzzy counters. The counter is not protected by any mutex and the results are not guaranteed to be 100% accurate but close diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 2ca9a22c06f..2d03231c22c 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2541,9 +2541,9 @@ dberr_t row_update_cascade_for_mysql( with a latch. */ dict_table_n_rows_dec(table); - srv_stats.n_rows_deleted.add((size_t)trx->id, 1); + srv_stats.n_rows_deleted.inc(); } else { - srv_stats.n_rows_updated.add((size_t)trx->id, 1); + srv_stats.n_rows_updated.inc(); } row_update_statistics_if_needed(table);