diff options
-rw-r--r-- | storage/innobase/buf/buf0lru.cc | 3 | ||||
-rw-r--r-- | storage/innobase/include/os0sync.h | 59 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 16 | ||||
-rw-r--r-- | storage/innobase/include/ut0counter.h | 98 | ||||
-rw-r--r-- | storage/innobase/lock/lock0wait.cc | 23 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 24 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0lru.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/include/os0sync.h | 58 | ||||
-rw-r--r-- | storage/xtradb/include/srv0srv.h | 16 | ||||
-rw-r--r-- | storage/xtradb/include/ut0counter.h | 98 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0wait.cc | 23 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 25 | ||||
-rw-r--r-- | storage/xtradb/row/row0sel.cc | 5 |
14 files changed, 219 insertions, 239 deletions
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 30b991d24cf..8c2b5df4bce 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1373,7 +1374,7 @@ loop: ++flush_failures; } - srv_stats.buf_pool_wait_free.add(n_iterations, 1); + srv_stats.buf_pool_wait_free.inc(); n_iterations++; diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index dd6de43dc0b..54032b5ad31 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -2,6 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -36,14 +37,13 @@ Created 9/6/1995 Heikki Tuuri #include "univ.i" #include "ut0lst.h" -#include "sync0types.h" -#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \ - || defined _M_X64 || defined __WIN__ - -#define IB_STRONG_MEMORY_MODEL - -#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */ +/** CPU cache line size */ +#ifdef __powerpc__ +#define CACHE_LINE_SIZE 128 +#else +#define CACHE_LINE_SIZE 64 +#endif #ifdef HAVE_WINDOWS_ATOMICS typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates @@ -889,6 +889,51 @@ for synchronization */ "Memory barrier is not used" #endif + +/** Simple counter aligned to CACHE_LINE_SIZE +@tparam Type the integer type of the counter +@tparam atomic whether to use atomic memory access */ +template <typename Type = ulint, bool atomic = false> +struct MY_ALIGNED(CACHE_LINE_SIZE) simple_counter +{ + /** Increment the counter */ + Type inc() { return add(1); } + /** Decrement the counter */ + Type dec() { return sub(1); } + + /** Add to the counter + @param[in] i amount to be added + @return the value of the counter after adding */ + Type add(Type i) + { + compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint)); + if (atomic) { + return os_atomic_increment_ulint(&m_counter, i); + } else { + return m_counter += i; + } + } + /** Subtract from the counter + @param[in] i amount to be subtracted + @return the value of the counter after adding */ + Type sub(Type i) + { + compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint)); + if (atomic) { + return os_atomic_decrement_ulint(&m_counter, i); + } else { + return m_counter -= i; + } + } + + /** @return the value of the counter (non-atomic access)! */ + operator Type() const { return m_counter; } + +private: + /** The counter */ + Type m_counter; +}; + #ifndef UNIV_NONINL #include "os0sync.ic" #endif diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 9753c442727..522eff23a0d 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -3,7 +3,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2009, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation Ab. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -55,11 +55,10 @@ Created 10/10/1995 Heikki Tuuri /* Global counters used inside InnoDB. */ struct srv_stats_t { - typedef ib_counter_t<lsn_t, 1, single_indexer_t> lsn_ctr_1_t; - typedef ib_counter_t<ulint, 1, single_indexer_t> ulint_ctr_1_t; - typedef ib_counter_t<lint, 1, single_indexer_t> lint_ctr_1_t; typedef ib_counter_t<ulint, 64> ulint_ctr_64_t; - typedef ib_counter_t<ib_int64_t, 1, single_indexer_t> ib_int64_ctr_1_t; + typedef simple_counter<lsn_t> lsn_ctr_1_t; + typedef simple_counter<ulint> ulint_ctr_1_t; + typedef simple_counter<ib_int64_t> ib_int64_ctr_1_t; /** Count the amount of data written in total (in bytes) */ ulint_ctr_1_t data_written; @@ -73,8 +72,9 @@ struct srv_stats_t { /** Amount of data written to the log files in bytes */ lsn_ctr_1_t os_log_written; - /** Number of writes being done to the log files */ - lint_ctr_1_t os_log_pending_writes; + /** Number of writes being done to the log files. + Protected by log_sys->write_mutex. */ + ulint_ctr_1_t os_log_pending_writes; /** We increase this counter, when we don't have enough space in the log buffer and have to flush it */ @@ -148,7 +148,7 @@ struct srv_stats_t { ulint_ctr_1_t n_lock_wait_count; /** Number of threads currently waiting on database locks */ - lint_ctr_1_t n_lock_wait_current_count; + simple_counter<ulint, true> n_lock_wait_current_count; /** Number of rows read. */ ulint_ctr_64_t n_rows_read; diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h index 63a133a175d..edc0db3b03d 100644 --- a/storage/innobase/include/ut0counter.h +++ b/storage/innobase/include/ut0counter.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -30,13 +31,7 @@ Created 2012/04/12 by Sunny Bains #include "univ.i" #include <string.h> #include "os0thread.h" - -/** CPU cache line size */ -#ifdef __powerpc__ -#define CACHE_LINE_SIZE 128 -#else -#define CACHE_LINE_SIZE 64 -#endif +#include "os0sync.h" /** Default number of slots to use in ib_counter_t */ #define IB_N_SLOTS 64 @@ -44,8 +39,6 @@ Created 2012/04/12 by Sunny Bains /** Get the offset into the counter array. */ template <typename Type, int N> struct generic_indexer_t { - /** Default constructor/destructor should be OK. */ - /** @return offset within m_counter */ size_t offset(size_t index) const UNIV_NOTHROW { return(((index % N) + 1) * (CACHE_LINE_SIZE / sizeof(Type))); @@ -58,8 +51,6 @@ struct generic_indexer_t { use the thread id. */ template <typename Type, int N> struct get_sched_indexer_t : public generic_indexer_t<Type, N> { - /** Default constructor/destructor should be OK. */ - /* @return result from sched_getcpu(), the thread id if it fails. */ size_t get_rnd_index() const UNIV_NOTHROW { @@ -76,31 +67,17 @@ struct get_sched_indexer_t : public generic_indexer_t<Type, N> { /** Use the thread id to index into the counter array. */ template <typename Type, int N> struct thread_id_indexer_t : public generic_indexer_t<Type, N> { - /** Default constructor/destructor should are OK. */ - /* @return a random number, currently we use the thread id. Where thread id is represented as a pointer, it may not work as effectively. */ size_t get_rnd_index() const UNIV_NOTHROW { return((lint) os_thread_get_curr_id()); } -}; - -/** For counters wher N=1 */ -template <typename Type, int N=1> -struct single_indexer_t { - /** Default constructor/destructor should are OK. */ - - /** @return offset within m_counter */ - size_t offset(size_t index) const UNIV_NOTHROW { - ut_ad(N == 1); - return((CACHE_LINE_SIZE / sizeof(Type))); - } - /* @return 1 */ - size_t get_rnd_index() const UNIV_NOTHROW { - ut_ad(N == 1); - return(1); + /** @return a random offset to the array */ + size_t get_rnd_offset() const UNIV_NOTHROW + { + return(generic_indexer_t<Type, N>::offset(get_rnd_index())); } }; @@ -112,17 +89,11 @@ template < typename Type, int N = IB_N_SLOTS, template<typename, int> class Indexer = thread_id_indexer_t> -class ib_counter_t { -public: - ib_counter_t() { memset(m_counter, 0x0, sizeof(m_counter)); } - +struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t +{ +#ifdef UNIV_DEBUG ~ib_counter_t() { - ut_ad(validate()); - } - - bool validate() UNIV_NOTHROW { -#ifdef UNIV_DEBUG size_t n = (CACHE_LINE_SIZE / sizeof(Type)); /* Check that we aren't writing outside our defined bounds. */ @@ -131,27 +102,23 @@ public: ut_ad(m_counter[i + j] == 0); } } -#endif /* UNIV_DEBUG */ - return(true); } +#endif /* UNIV_DEBUG */ - /** If you can't use a good index id. Increment by 1. */ + /** Increment the counter by 1. */ void inc() UNIV_NOTHROW { add(1); } - /** If you can't use a good index id. - * @param n - is the amount to increment */ - void add(Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(m_policy.get_rnd_index()); - - ut_ad(i < UT_ARR_SIZE(m_counter)); + /** Increment the counter by 1. + @param[in] index a reasonably thread-unique identifier */ + void inc(size_t index) UNIV_NOTHROW { add(index, 1); } - m_counter[i] += n; - } + /** Add to the counter. + @param[in] n amount to be added */ + void add(Type n) UNIV_NOTHROW { add(m_policy.get_rnd_offset(), n); } - /** Use this if you can use a unique indentifier, saves a - call to get_rnd_index(). - @param i - index into a slot - @param n - amount to increment */ + /** Add to the counter. + @param[in] index a reasonably thread-unique identifier + @param[in] n amount to be added */ void add(size_t index, Type n) UNIV_NOTHROW { size_t i = m_policy.offset(index); @@ -160,31 +127,6 @@ public: m_counter[i] += n; } - /** If you can't use a good index id. Decrement by 1. */ - void dec() UNIV_NOTHROW { sub(1); } - - /** If you can't use a good index id. - * @param - n is the amount to decrement */ - void sub(Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(m_policy.get_rnd_index()); - - ut_ad(i < UT_ARR_SIZE(m_counter)); - - m_counter[i] -= n; - } - - /** Use this if you can use a unique indentifier, saves a - call to get_rnd_index(). - @param i - index into a slot - @param n - amount to decrement */ - void sub(size_t index, Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(index); - - ut_ad(i < UT_ARR_SIZE(m_counter)); - - m_counter[i] -= n; - } - /* @return total value - not 100% accurate, since it is not atomic. */ operator Type() const UNIV_NOTHROW { Type total = 0; diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index 8f9ea7e10aa..a447027e336 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -273,6 +273,9 @@ lock_wait_suspend_thread( slot = lock_wait_table_reserve_slot(thr, lock_wait_timeout); + lock_wait_mutex_exit(); + trx_mutex_exit(trx); + if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_stats.n_lock_wait_count.inc(); srv_stats.n_lock_wait_current_count.inc(); @@ -284,19 +287,21 @@ lock_wait_suspend_thread( } } - lock_wait_mutex_exit(); - trx_mutex_exit(trx); - ulint lock_type = ULINT_UNDEFINED; - lock_mutex_enter(); - + /* The wait_lock can be cleared by another thread when the + lock is released. But the wait can only be initiated by the + current thread which owns the transaction. Only acquire the + mutex if the wait_lock is still active. */ if (const lock_t* wait_lock = trx->lock.wait_lock) { - lock_type = lock_get_type_low(wait_lock); + lock_mutex_enter(); + wait_lock = trx->lock.wait_lock; + if (wait_lock) { + lock_type = lock_get_type_low(wait_lock); + } + lock_mutex_exit(); } - lock_mutex_exit(); - had_dict_lock = trx->dict_operation_lock_mode; switch (had_dict_lock) { diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 7bd384347cb..717fd6bde0c 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1509,9 +1509,9 @@ error_exit: que_thr_stop_for_mysql_no_error(thr, trx); if (table->is_system_db) { - srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1); + srv_stats.n_system_rows_inserted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_inserted.add((size_t)trx->id, 1); + srv_stats.n_rows_inserted.inc(size_t(trx->id)); } /* Not protected by dict_table_stats_lock() for performance @@ -1892,18 +1892,16 @@ run_again: dict_table_n_rows_dec(prebuilt->table); if (table->is_system_db) { - srv_stats.n_system_rows_deleted.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_deleted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_deleted.add((size_t)trx->id, 1); + srv_stats.n_rows_deleted.inc(size_t(trx->id)); } } else { if (table->is_system_db) { - srv_stats.n_system_rows_updated.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_updated.inc(size_t(trx->id)); } else { - srv_stats.n_rows_updated.add((size_t)trx->id, 1); + srv_stats.n_rows_updated.inc(size_t(trx->id)); } } @@ -2136,17 +2134,15 @@ run_again: dict_table_n_rows_dec(table); if (table->is_system_db) { - srv_stats.n_system_rows_deleted.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_deleted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_deleted.add((size_t)trx->id, 1); + srv_stats.n_rows_deleted.inc(size_t(trx->id)); } } else { if (table->is_system_db) { - srv_stats.n_system_rows_updated.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_updated.inc(size_t(trx->id)); } else { - srv_stats.n_rows_updated.add((size_t)trx->id, 1); + srv_stats.n_rows_updated.inc(size_t(trx->id)); } } diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 6d1be59904f..10b071c048b 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3035,11 +3035,12 @@ row_sel_get_clust_rec_for_mysql( dberr_t err; trx_t* trx; - srv_stats.n_sec_rec_cluster_reads.inc(); - *out_rec = NULL; trx = thr_get_trx(thr); + srv_stats.n_sec_rec_cluster_reads.inc( + thd_get_thread_id(trx->mysql_thd)); + row_build_row_ref_in_tuple(prebuilt->clust_ref, rec, sec_index, *offsets, trx); diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index dff67c0fad6..d979eb44a96 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1501,7 +1502,7 @@ loop: n_iterations++; - srv_stats.buf_pool_wait_free.add(n_iterations, 1); + srv_stats.buf_pool_wait_free.inc(); /* In case of backoff, do not ever attempt single page flushes and wait for the cleaner to free some pages instead. */ @@ -1595,7 +1596,7 @@ loop: ++flush_failures; } - srv_stats.buf_pool_wait_free.add(n_iterations, 1); + srv_stats.buf_pool_wait_free.inc(); n_iterations++; diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 48c56a73369..b152ab53e68 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -2,6 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -38,12 +39,12 @@ Created 9/6/1995 Heikki Tuuri #include "ut0lst.h" #include "sync0types.h" -#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \ - || defined _M_X64 || defined __WIN__ - -#define IB_STRONG_MEMORY_MODEL - -#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */ +/** CPU cache line size */ +#ifdef __powerpc__ +#define CACHE_LINE_SIZE 128 +#else +#define CACHE_LINE_SIZE 64 +#endif #ifdef HAVE_WINDOWS_ATOMICS typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates @@ -940,6 +941,51 @@ for synchronization */ "Memory barrier is not used" #endif + +/** Simple counter aligned to CACHE_LINE_SIZE +@tparam Type the integer type of the counter +@tparam atomic whether to use atomic memory access */ +template <typename Type = ulint, bool atomic = false> +struct MY_ALIGNED(CACHE_LINE_SIZE) simple_counter +{ + /** Increment the counter */ + Type inc() { return add(1); } + /** Decrement the counter */ + Type dec() { return sub(1); } + + /** Add to the counter + @param[in] i amount to be added + @return the value of the counter after adding */ + Type add(Type i) + { + compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint)); + if (atomic) { + return os_atomic_increment_ulint(&m_counter, i); + } else { + return m_counter += i; + } + } + /** Subtract from the counter + @param[in] i amount to be subtracted + @return the value of the counter after adding */ + Type sub(Type i) + { + compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint)); + if (atomic) { + return os_atomic_decrement_ulint(&m_counter, i); + } else { + return m_counter -= i; + } + } + + /** @return the value of the counter (non-atomic access)! */ + operator Type() const { return m_counter; } + +private: + /** The counter */ + Type m_counter; +}; + #ifndef UNIV_NONINL #include "os0sync.ic" #endif diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 6a962262f69..c07a8db1bb3 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -3,7 +3,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2009, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation Ab. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -55,11 +55,10 @@ Created 10/10/1995 Heikki Tuuri /* Global counters used inside InnoDB. */ struct srv_stats_t { - typedef ib_counter_t<lsn_t, 1, single_indexer_t> lsn_ctr_1_t; - typedef ib_counter_t<ulint, 1, single_indexer_t> ulint_ctr_1_t; - typedef ib_counter_t<lint, 1, single_indexer_t> lint_ctr_1_t; typedef ib_counter_t<ulint, 64> ulint_ctr_64_t; - typedef ib_counter_t<ib_int64_t, 1, single_indexer_t> ib_int64_ctr_1_t; + typedef simple_counter<lsn_t> lsn_ctr_1_t; + typedef simple_counter<ulint> ulint_ctr_1_t; + typedef simple_counter<ib_int64_t> ib_int64_ctr_1_t; /** Count the amount of data written in total (in bytes) */ ulint_ctr_1_t data_written; @@ -73,8 +72,9 @@ struct srv_stats_t { /** Amount of data written to the log files in bytes */ lsn_ctr_1_t os_log_written; - /** Number of writes being done to the log files */ - lint_ctr_1_t os_log_pending_writes; + /** Number of writes being done to the log files. + Protected by log_sys->write_mutex. */ + ulint_ctr_1_t os_log_pending_writes; /** We increase this counter, when we don't have enough space in the log buffer and have to flush it */ @@ -148,7 +148,7 @@ struct srv_stats_t { ulint_ctr_1_t n_lock_wait_count; /** Number of threads currently waiting on database locks */ - lint_ctr_1_t n_lock_wait_current_count; + simple_counter<ulint, true> n_lock_wait_current_count; /** Number of rows read. */ ulint_ctr_64_t n_rows_read; diff --git a/storage/xtradb/include/ut0counter.h b/storage/xtradb/include/ut0counter.h index 63a133a175d..edc0db3b03d 100644 --- a/storage/xtradb/include/ut0counter.h +++ b/storage/xtradb/include/ut0counter.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -30,13 +31,7 @@ Created 2012/04/12 by Sunny Bains #include "univ.i" #include <string.h> #include "os0thread.h" - -/** CPU cache line size */ -#ifdef __powerpc__ -#define CACHE_LINE_SIZE 128 -#else -#define CACHE_LINE_SIZE 64 -#endif +#include "os0sync.h" /** Default number of slots to use in ib_counter_t */ #define IB_N_SLOTS 64 @@ -44,8 +39,6 @@ Created 2012/04/12 by Sunny Bains /** Get the offset into the counter array. */ template <typename Type, int N> struct generic_indexer_t { - /** Default constructor/destructor should be OK. */ - /** @return offset within m_counter */ size_t offset(size_t index) const UNIV_NOTHROW { return(((index % N) + 1) * (CACHE_LINE_SIZE / sizeof(Type))); @@ -58,8 +51,6 @@ struct generic_indexer_t { use the thread id. */ template <typename Type, int N> struct get_sched_indexer_t : public generic_indexer_t<Type, N> { - /** Default constructor/destructor should be OK. */ - /* @return result from sched_getcpu(), the thread id if it fails. */ size_t get_rnd_index() const UNIV_NOTHROW { @@ -76,31 +67,17 @@ struct get_sched_indexer_t : public generic_indexer_t<Type, N> { /** Use the thread id to index into the counter array. */ template <typename Type, int N> struct thread_id_indexer_t : public generic_indexer_t<Type, N> { - /** Default constructor/destructor should are OK. */ - /* @return a random number, currently we use the thread id. Where thread id is represented as a pointer, it may not work as effectively. */ size_t get_rnd_index() const UNIV_NOTHROW { return((lint) os_thread_get_curr_id()); } -}; - -/** For counters wher N=1 */ -template <typename Type, int N=1> -struct single_indexer_t { - /** Default constructor/destructor should are OK. */ - - /** @return offset within m_counter */ - size_t offset(size_t index) const UNIV_NOTHROW { - ut_ad(N == 1); - return((CACHE_LINE_SIZE / sizeof(Type))); - } - /* @return 1 */ - size_t get_rnd_index() const UNIV_NOTHROW { - ut_ad(N == 1); - return(1); + /** @return a random offset to the array */ + size_t get_rnd_offset() const UNIV_NOTHROW + { + return(generic_indexer_t<Type, N>::offset(get_rnd_index())); } }; @@ -112,17 +89,11 @@ template < typename Type, int N = IB_N_SLOTS, template<typename, int> class Indexer = thread_id_indexer_t> -class ib_counter_t { -public: - ib_counter_t() { memset(m_counter, 0x0, sizeof(m_counter)); } - +struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t +{ +#ifdef UNIV_DEBUG ~ib_counter_t() { - ut_ad(validate()); - } - - bool validate() UNIV_NOTHROW { -#ifdef UNIV_DEBUG size_t n = (CACHE_LINE_SIZE / sizeof(Type)); /* Check that we aren't writing outside our defined bounds. */ @@ -131,27 +102,23 @@ public: ut_ad(m_counter[i + j] == 0); } } -#endif /* UNIV_DEBUG */ - return(true); } +#endif /* UNIV_DEBUG */ - /** If you can't use a good index id. Increment by 1. */ + /** Increment the counter by 1. */ void inc() UNIV_NOTHROW { add(1); } - /** If you can't use a good index id. - * @param n - is the amount to increment */ - void add(Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(m_policy.get_rnd_index()); - - ut_ad(i < UT_ARR_SIZE(m_counter)); + /** Increment the counter by 1. + @param[in] index a reasonably thread-unique identifier */ + void inc(size_t index) UNIV_NOTHROW { add(index, 1); } - m_counter[i] += n; - } + /** Add to the counter. + @param[in] n amount to be added */ + void add(Type n) UNIV_NOTHROW { add(m_policy.get_rnd_offset(), n); } - /** Use this if you can use a unique indentifier, saves a - call to get_rnd_index(). - @param i - index into a slot - @param n - amount to increment */ + /** Add to the counter. + @param[in] index a reasonably thread-unique identifier + @param[in] n amount to be added */ void add(size_t index, Type n) UNIV_NOTHROW { size_t i = m_policy.offset(index); @@ -160,31 +127,6 @@ public: m_counter[i] += n; } - /** If you can't use a good index id. Decrement by 1. */ - void dec() UNIV_NOTHROW { sub(1); } - - /** If you can't use a good index id. - * @param - n is the amount to decrement */ - void sub(Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(m_policy.get_rnd_index()); - - ut_ad(i < UT_ARR_SIZE(m_counter)); - - m_counter[i] -= n; - } - - /** Use this if you can use a unique indentifier, saves a - call to get_rnd_index(). - @param i - index into a slot - @param n - amount to decrement */ - void sub(size_t index, Type n) UNIV_NOTHROW { - size_t i = m_policy.offset(index); - - ut_ad(i < UT_ARR_SIZE(m_counter)); - - m_counter[i] -= n; - } - /* @return total value - not 100% accurate, since it is not atomic. */ operator Type() const UNIV_NOTHROW { Type total = 0; diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index 8f9ea7e10aa..a447027e336 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -273,6 +273,9 @@ lock_wait_suspend_thread( slot = lock_wait_table_reserve_slot(thr, lock_wait_timeout); + lock_wait_mutex_exit(); + trx_mutex_exit(trx); + if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_stats.n_lock_wait_count.inc(); srv_stats.n_lock_wait_current_count.inc(); @@ -284,19 +287,21 @@ lock_wait_suspend_thread( } } - lock_wait_mutex_exit(); - trx_mutex_exit(trx); - ulint lock_type = ULINT_UNDEFINED; - lock_mutex_enter(); - + /* The wait_lock can be cleared by another thread when the + lock is released. But the wait can only be initiated by the + current thread which owns the transaction. Only acquire the + mutex if the wait_lock is still active. */ if (const lock_t* wait_lock = trx->lock.wait_lock) { - lock_type = lock_get_type_low(wait_lock); + lock_mutex_enter(); + wait_lock = trx->lock.wait_lock; + if (wait_lock) { + lock_type = lock_get_type_low(wait_lock); + } + lock_mutex_exit(); } - lock_mutex_exit(); - had_dict_lock = trx->dict_operation_lock_mode; switch (had_dict_lock) { diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index b4d359d5009..463981f51dd 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1514,11 +1514,10 @@ error_exit: que_thr_stop_for_mysql_no_error(thr, trx); if (UNIV_LIKELY(!(trx->fake_changes))) { - if (table->is_system_db) { - srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1); + srv_stats.n_system_rows_inserted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_inserted.add((size_t)trx->id, 1); + srv_stats.n_rows_inserted.inc(size_t(trx->id)); } if (prebuilt->clust_index_was_generated) { @@ -1907,17 +1906,15 @@ run_again: dict_table_n_rows_dec(prebuilt->table); if (table->is_system_db) { - srv_stats.n_system_rows_deleted.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_deleted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_deleted.add((size_t)trx->id, 1); + srv_stats.n_rows_deleted.inc(size_t(trx->id)); } } else { if (table->is_system_db) { - srv_stats.n_system_rows_updated.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_updated.inc(size_t(trx->id)); } else { - srv_stats.n_rows_updated.add((size_t)trx->id, 1); + srv_stats.n_rows_updated.inc(size_t(trx->id)); } } @@ -2155,17 +2152,15 @@ run_again: dict_table_n_rows_dec(table); if (table->is_system_db) { - srv_stats.n_system_rows_deleted.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_deleted.inc(size_t(trx->id)); } else { - srv_stats.n_rows_deleted.add((size_t)trx->id, 1); + srv_stats.n_rows_deleted.inc(size_t(trx->id)); } } else { if (table->is_system_db) { - srv_stats.n_system_rows_updated.add( - (size_t)trx->id, 1); + srv_stats.n_system_rows_updated.inc(size_t(trx->id)); } else { - srv_stats.n_rows_updated.add((size_t)trx->id, 1); + srv_stats.n_rows_updated.inc(size_t(trx->id)); } } diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 9a583e2023a..7d4435eba5b 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -3047,11 +3047,12 @@ row_sel_get_clust_rec_for_mysql( dberr_t err; trx_t* trx; - srv_stats.n_sec_rec_cluster_reads.inc(); - *out_rec = NULL; trx = thr_get_trx(thr); + srv_stats.n_sec_rec_cluster_reads.inc( + thd_get_thread_id(trx->mysql_thd)); + row_build_row_ref_in_tuple(prebuilt->clust_ref, rec, sec_index, *offsets, trx); |