summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-05-12 13:29:24 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-05-12 13:29:24 +0300
commitb9474b5d5185f8ddb639952c1c86d1dd1d42da35 (patch)
treea2690f2647cac1814dbeac5f1bb624bf016461cf
parent993323995648526781e5d22afbc77e260529a8b0 (diff)
parent03dca7a3337f4f8e718c52a95e793bbc2c9ffa2c (diff)
downloadmariadb-git-b9474b5d5185f8ddb639952c1c86d1dd1d42da35.tar.gz
Merge 10.1 into 10.2
-rw-r--r--storage/innobase/buf/buf0lru.cc2
-rw-r--r--storage/innobase/include/srv0srv.h14
-rw-r--r--storage/innobase/include/ut0counter.h93
-rw-r--r--storage/innobase/lock/lock0wait.cc23
-rw-r--r--storage/innobase/row/row0mysql.cc18
-rw-r--r--storage/innobase/row/row0sel.cc5
-rw-r--r--storage/xtradb/buf/buf0lru.cc5
-rw-r--r--storage/xtradb/buf/buf0rea.cc6
-rw-r--r--storage/xtradb/fil/fil0crypt.cc16
-rw-r--r--storage/xtradb/include/os0sync.h57
-rw-r--r--storage/xtradb/include/srv0srv.h16
-rw-r--r--storage/xtradb/include/ut0counter.h90
-rw-r--r--storage/xtradb/lock/lock0wait.cc23
-rw-r--r--storage/xtradb/row/row0mysql.cc25
-rw-r--r--storage/xtradb/row/row0sel.cc5
15 files changed, 170 insertions, 228 deletions
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 10a8561d38d..1e7b7065b12 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1420,7 +1420,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/srv0srv.h b/storage/innobase/include/srv0srv.h
index 230d7b7effe..d66593c686c 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -62,10 +62,9 @@ struct fil_space_t;
/* Global counters used inside InnoDB. */
struct srv_stats_t {
typedef ib_counter_t<ulint, 64> ulint_ctr_64_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<int64_t, 1, single_indexer_t> int64_ctr_1_t;
+ typedef simple_counter<lsn_t> lsn_ctr_1_t;
+ typedef simple_counter<ulint> ulint_ctr_1_t;
+ typedef simple_counter<int64_t> int64_ctr_1_t;
/** Count the amount of data written in total (in bytes) */
ulint_ctr_1_t data_written;
@@ -82,8 +81,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 */
@@ -141,7 +141,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 70381f26a84..aa710a5ae96 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, 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
@@ -44,8 +45,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 */
static size_t offset(size_t index) UNIV_NOTHROW
{
@@ -59,9 +58,6 @@ template <typename Type=ulint, int N=1>
struct counter_indexer_t : public generic_indexer_t<Type, N> {
/** Default constructor/destructor should be OK. */
-
- enum { fast = 1 };
-
/** @return result from RDTSC or similar functions. */
static size_t get_rnd_index() UNIV_NOTHROW
{
@@ -84,28 +80,6 @@ struct counter_indexer_t : public generic_indexer_t<Type, N> {
}
};
-/** For counters where N=1 */
-template <typename Type=ulint, int N=1>
-struct single_indexer_t {
- /** Default constructor/destructor should are OK. */
-
- enum { fast = 0 };
-
- /** @return offset within m_counter */
- static size_t offset(size_t index) UNIV_NOTHROW
- {
- ut_ad(N == 1);
- return((CACHE_LINE_SIZE / sizeof(Type)));
- }
-
- /** @return 1 */
- static size_t get_rnd_index() UNIV_NOTHROW
- {
- ut_ad(N == 1);
- return(1);
- }
-};
-
#define default_indexer_t counter_indexer_t
/** Class for using fuzzy counters. The counter is not protected by any
@@ -116,19 +90,11 @@ template <
typename Type,
int N = IB_N_SLOTS,
template<typename, int> class Indexer = default_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());
- }
-
- static bool is_fast() { return(Indexer<Type, N>::fast); }
-
- 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. */
@@ -137,27 +103,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 identifier, 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);
@@ -166,31 +128,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 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 identifier, 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 30752706475..0954ad9430a 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) 2014, 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
@@ -263,6 +263,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();
@@ -274,19 +277,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();
-
ulint 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 23fc8da3e9c..8cb146c40f3 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1633,9 +1633,9 @@ error_exit:
que_thr_stop_for_mysql_no_error(thr, trx);
if (table->is_system_db) {
- srv_stats.n_system_rows_inserted.inc();
+ srv_stats.n_system_rows_inserted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_inserted.inc();
+ srv_stats.n_rows_inserted.inc(size_t(trx->id));
}
/* Not protected by dict_table_stats_lock() for performance
@@ -2114,9 +2114,9 @@ run_again:
than protecting the following code with a latch. */
dict_table_n_rows_dec(node->table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.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));
}
row_update_statistics_if_needed(node->table);
@@ -2130,17 +2130,17 @@ run_again:
with a latch. */
dict_table_n_rows_dec(prebuilt->table);
- if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.inc();
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.inc();
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.inc();
+ 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 c4a87bde2cb..edef2d22fa8 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -3363,11 +3363,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/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index 85b04d37a08..b2b737b8d40 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 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
@@ -416,6 +416,7 @@ read_ahead:
switch(err) {
case DB_SUCCESS:
+ case DB_ERROR:
break;
case DB_TABLESPACE_DELETED:
ib_logf(IB_LOG_LEVEL_WARN,
@@ -557,6 +558,7 @@ buf_read_page_async(
switch(err) {
case DB_SUCCESS:
+ case DB_ERROR:
break;
case DB_TABLESPACE_DELETED:
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -848,6 +850,7 @@ buf_read_ahead_linear(
switch(err) {
case DB_SUCCESS:
+ case DB_ERROR:
break;
case DB_TABLESPACE_DELETED:
ib_logf(IB_LOG_LEVEL_WARN,
@@ -950,6 +953,7 @@ buf_read_ibuf_merge_pages(
switch(err) {
case DB_SUCCESS:
+ case DB_ERROR:
break;
case DB_TABLESPACE_DELETED:
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 6a1b2f310fb..e27e93244ae 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -537,16 +537,16 @@ fil_parse_write_crypt_data(
ptr += len;
/* update fil_space memory cache with crypt_data */
- fil_space_t* space = fil_space_acquire_silent(space_id);
-
- if (space) {
+ if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
crypt_data = fil_space_set_crypt_data(space, crypt_data);
fil_space_release(space);
- }
-
- /* Check is used key found from encryption plugin */
- if (crypt_data->should_encrypt() && !crypt_data->is_key_found()) {
- *err = DB_DECRYPTION_FAILED;
+ /* Check is used key found from encryption plugin */
+ if (crypt_data->should_encrypt()
+ && !crypt_data->is_key_found()) {
+ *err = DB_DECRYPTION_FAILED;
+ }
+ } else {
+ fil_space_destroy_crypt_data(&crypt_data);
}
return ptr;
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 48c56a73369..62f651413e1 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,11 @@ 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__ */
+#ifdef CPU_LEVEL1_DCACHE_LINESIZE
+# define CACHE_LINE_SIZE CPU_LEVEL1_DCACHE_LINESIZE
+#else
+# error CPU_LEVEL1_DCACHE_LINESIZE is undefined
+#endif /* CPU_LEVEL1_DCACHE_LINESIZE */
#ifdef HAVE_WINDOWS_ATOMICS
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
@@ -940,6 +940,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 74c118b7660..cf7824d91e7 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 447484ba985..4f736428a17 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
@@ -48,8 +49,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)));
@@ -62,8 +61,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 {
@@ -80,31 +77,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()));
}
};
@@ -116,17 +99,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. */
@@ -135,27 +112,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);
@@ -164,31 +137,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);