summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-05-12 13:12:45 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-05-12 13:12:45 +0300
commit03dca7a3337f4f8e718c52a95e793bbc2c9ffa2c (patch)
tree5fb404f1256b8a4a6e3a9c714633f8b3b231c723 /storage/innobase
parentd7cfe2c4f333300e02bfaf1280d9f61f81a7bc03 (diff)
parentff166093741df0bd91ba24e02714ef882073c51b (diff)
downloadmariadb-git-03dca7a3337f4f8e718c52a95e793bbc2c9ffa2c.tar.gz
Merge 10.0 into 10.1
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/buf/buf0lru.cc3
-rw-r--r--storage/innobase/include/os0sync.h59
-rw-r--r--storage/innobase/include/srv0srv.h16
-rw-r--r--storage/innobase/include/ut0counter.h98
-rw-r--r--storage/innobase/lock/lock0wait.cc23
-rw-r--r--storage/innobase/row/row0mysql.cc24
-rw-r--r--storage/innobase/row/row0sel.cc5
7 files changed, 109 insertions, 119 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);