mirror of
https://github.com/MariaDB/server.git
synced 2025-12-01 17:39:21 +03:00
Remove trx_t::has_search_latch and simplify debug code
When the btr_search_latch was split into an array of latches in MySQL 5.7.8 as part of the Oracle Bug#20985298 fix, the "caching" of the latch across storage engine API calls was removed, and the field trx->has_search_latch would only be set during a short time frame in the execution of row_search_mvcc(), which was formerly called row_search_for_mysql(). This means that the column INFORMATION_SCHEMA.INNODB_TRX.TRX_ADAPTIVE_HASH_LATCHED will always report 0. That column cannot be removed in MariaDB 10.2, but it can be removed in future releases. trx_t::has_search_latch: Remove. trx_assert_no_search_latch(): Remove. row_sel_try_search_shortcut_for_mysql(): Remove a redundant condition on trx->has_search_latch (it was always true). sync_check_iterate(): Make the parameter const. sync_check_functor_t: Make the operator() const, and remove result() and the virtual destructor. There is no need to have mutable state in the functors. sync_checker<bool>: Replaces dict_sync_check and btrsea_sync_check. sync_check: Replaces btrsea_sync_check. dict_sync_check: Instantiated from sync_checker. sync_allowed_latches: Use std::find() directly on the array. Remove the std::vector. TrxInInnoDB::enter(), TrxInInnoDB::exit(): Remove obviously redundant debug assertions on trx->in_depth, and use equality comparison against 0 because it could be more efficient on some architectures.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2014, 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
|
||||
@@ -991,11 +992,7 @@ BtrBulk::finish(dberr_t err)
|
||||
ut_ad(err == DB_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
dict_sync_check check(true);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
#endif /* UNIV_DEBUG */
|
||||
ut_ad(!sync_check_iterate(dict_sync_check()));
|
||||
|
||||
ut_ad(err != DB_SUCCESS || btr_validate_index(m_index, NULL, false));
|
||||
return(err);
|
||||
|
||||
@@ -1870,15 +1870,8 @@ buf_flush_batch(
|
||||
counts */
|
||||
{
|
||||
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_sync_check check(true);
|
||||
|
||||
ut_ad(flush_type != BUF_FLUSH_LIST
|
||||
|| !sync_check_iterate(check));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
ut_ad(flush_type == BUF_FLUSH_LRU
|
||||
|| !sync_check_iterate(dict_sync_check()));
|
||||
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
|
||||
|
||||
@@ -6113,14 +6113,7 @@ dict_set_corrupted(
|
||||
ut_ad(mutex_own(&dict_sys->mutex));
|
||||
ut_ad(!dict_table_is_comp(dict_sys->sys_tables));
|
||||
ut_ad(!dict_table_is_comp(dict_sys->sys_indexes));
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_sync_check check(true);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
ut_ad(!sync_check_iterate(dict_sync_check()));
|
||||
|
||||
/* Mark the table as corrupted only if the clustered index
|
||||
is corrupted */
|
||||
|
||||
@@ -1869,6 +1869,8 @@ void
|
||||
innobase_srv_conc_exit_innodb(
|
||||
row_prebuilt_t* prebuilt)
|
||||
{
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_on(prebuilt->trx->mysql_thd) &&
|
||||
wsrep_thd_is_BF(prebuilt->trx->mysql_thd, FALSE)) {
|
||||
@@ -1877,13 +1879,6 @@ innobase_srv_conc_exit_innodb(
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
trx_t* trx = prebuilt->trx;
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/* This is to avoid making an unnecessary function call. */
|
||||
if (trx->declared_to_be_inside_innodb
|
||||
@@ -1901,13 +1896,7 @@ innobase_srv_conc_force_exit_innodb(
|
||||
/*================================*/
|
||||
trx_t* trx) /*!< in: transaction handle */
|
||||
{
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
/* This is to avoid making an unnecessary function call. */
|
||||
if (trx->declared_to_be_inside_innodb) {
|
||||
@@ -1994,13 +1983,7 @@ const char*
|
||||
thd_innodb_tmpdir(
|
||||
THD* thd)
|
||||
{
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
trx_t* trx = thd_to_trx(thd);
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
const char* tmp_dir = THDVAR(thd, tmpdir);
|
||||
|
||||
@@ -3360,7 +3343,6 @@ innobase_query_caching_of_table_permitted(
|
||||
return(false);
|
||||
}
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
innobase_srv_conc_force_exit_innodb(trx);
|
||||
|
||||
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)
|
||||
@@ -3668,8 +3650,6 @@ ha_innobase::init_table_handle_for_HANDLER(void)
|
||||
/* Initialize the m_prebuilt struct much like it would be inited in
|
||||
external_lock */
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
|
||||
innobase_srv_conc_force_exit_innodb(m_prebuilt->trx);
|
||||
|
||||
/* If the transaction is not started yet, start it */
|
||||
@@ -4781,12 +4761,6 @@ innobase_commit_ordered(
|
||||
trx = check_trx_exists(thd);
|
||||
TrxInInnoDB trx_in_innodb(trx);
|
||||
|
||||
/* Since we will reserve the kernel mutex, we must not be holding the
|
||||
search system latch, or we will disobey the latching order. But we
|
||||
already released it in innobase_xa_prepare() (if not before), so just
|
||||
have an assert here.*/
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) {
|
||||
/* We cannot throw error here; instead we will catch this error
|
||||
again in innobase_commit() and report it from there. */
|
||||
@@ -4998,12 +4972,6 @@ innobase_rollback_trx(
|
||||
DBUG_ENTER("innobase_rollback_trx");
|
||||
DBUG_PRINT("trans", ("aborting transaction"));
|
||||
|
||||
/* Release a possible FIFO ticket and search latch. Since we will
|
||||
reserve the trx_sys->mutex, we have to release the search system
|
||||
latch first to obey the latching order. */
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
innobase_srv_conc_force_exit_innodb(trx);
|
||||
|
||||
/* If we had reserved the auto-inc lock for some table (if
|
||||
@@ -13101,10 +13069,6 @@ create_table_info_t::initialize()
|
||||
|
||||
parent_trx = check_trx_exists(m_thd);
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
||||
trx_assert_no_search_latch(parent_trx);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@@ -13953,12 +13917,6 @@ innobase_drop_database(
|
||||
|
||||
THD* thd = current_thd;
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT
|
||||
query, release possible adaptive hash latch to avoid
|
||||
deadlocks of threads */
|
||||
|
||||
trx_assert_no_search_latch(check_trx_exists(thd));
|
||||
|
||||
ulint len = 0;
|
||||
char* ptr = strend(path) - 2;
|
||||
|
||||
@@ -14692,12 +14650,7 @@ ha_innobase::info_low(
|
||||
|
||||
update_thd(ha_thd());
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"returning various info to MariaDB";
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
m_prebuilt->trx->op_info = "returning various info to MariaDB";
|
||||
|
||||
ib_table = m_prebuilt->table;
|
||||
DBUG_ASSERT(ib_table->n_ref_count > 0);
|
||||
@@ -15544,12 +15497,7 @@ ha_innobase::update_table_comment(
|
||||
|
||||
update_thd(ha_thd());
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"returning table comment";
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
m_prebuilt->trx->op_info = "returning table comment";
|
||||
|
||||
#define SSTR( x ) reinterpret_cast< std::ostringstream & >( \
|
||||
( std::ostringstream() << std::dec << x ) ).str()
|
||||
@@ -15605,22 +15553,14 @@ ha_innobase::get_foreign_key_create_info(void)
|
||||
|
||||
update_thd(ha_thd());
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"getting info on foreign keys";
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query,
|
||||
release possible adaptive hash latch to avoid
|
||||
deadlocks of threads */
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
|
||||
|
||||
m_prebuilt->trx->op_info = "getting info on foreign keys";
|
||||
|
||||
/* Output the data to a temporary string */
|
||||
std::string str = dict_print_info_on_foreign_keys(
|
||||
TRUE, m_prebuilt->trx,
|
||||
m_prebuilt->table);
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"";
|
||||
m_prebuilt->trx->op_info = "";
|
||||
|
||||
/* Allocate buffer for the string */
|
||||
char* fk_str = (char*) my_malloc(str.length() + 1, MYF(0));
|
||||
@@ -16624,8 +16564,6 @@ innodb_show_status(
|
||||
|
||||
trx_t* trx = check_trx_exists(thd);
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
innobase_srv_conc_force_exit_innodb(trx);
|
||||
|
||||
TrxInInnoDB trx_in_innodb(trx);
|
||||
@@ -17936,12 +17874,6 @@ innobase_xa_prepare(
|
||||
|
||||
thd_get_xid(thd, (MYSQL_XID*) trx->xid);
|
||||
|
||||
/* Release a possible FIFO ticket and search latch. Since we will
|
||||
reserve the trx_sys->mutex, we have to release the search system
|
||||
latch first to obey the latching order. */
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
innobase_srv_conc_force_exit_innodb(trx);
|
||||
|
||||
TrxInInnoDB trx_in_innodb(trx);
|
||||
|
||||
@@ -3020,11 +3020,6 @@ ha_innopart::records_in_range(
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"estimating records in index range";
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads. */
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
|
||||
active_index = keynr;
|
||||
|
||||
key = table->key_info + active_index;
|
||||
@@ -3159,11 +3154,6 @@ ha_innopart::estimate_rows_upper_bound()
|
||||
|
||||
m_prebuilt->trx->op_info = "calculating upper bound for table rows";
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads. */
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
|
||||
for (uint i = m_part_info->get_first_used_partition();
|
||||
i < m_tot_parts;
|
||||
i = m_part_info->get_next_used_partition(i)) {
|
||||
@@ -3275,12 +3265,7 @@ ha_innopart::info_low(
|
||||
|
||||
update_thd(ha_thd());
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads. */
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"returning various info to MySQL";
|
||||
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
m_prebuilt->trx->op_info = "returning various info to MySQL";
|
||||
|
||||
ut_ad(m_part_share->get_table_part(0)->n_ref_count > 0);
|
||||
|
||||
|
||||
@@ -591,7 +591,6 @@ ha_innobase::check_if_supported_inplace_alter(
|
||||
}
|
||||
|
||||
update_thd();
|
||||
trx_assert_no_search_latch(m_prebuilt->trx);
|
||||
|
||||
/* Change on engine specific table options require rebuild of the
|
||||
table */
|
||||
|
||||
@@ -699,8 +699,7 @@ fill_innodb_trx_from_cache(
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* trx_adaptive_hash_latched */
|
||||
OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store(
|
||||
row->trx_has_search_latch, true));
|
||||
OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store(0, true));
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/* trx_is_read_only*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 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
|
||||
@@ -479,11 +480,11 @@ void
|
||||
log_free_check(void)
|
||||
/*================*/
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
/* During row_log_table_apply(), this function will be called while we
|
||||
are holding some latches. This is OK, as long as we are not holding
|
||||
any latches on buffer blocks. */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
static const latch_level_t latches[] = {
|
||||
SYNC_DICT, /* dict_sys->mutex during
|
||||
commit_try_rebuild() */
|
||||
@@ -491,13 +492,12 @@ log_free_check(void)
|
||||
commit_try_rebuild() */
|
||||
SYNC_INDEX_TREE /* index->lock */
|
||||
};
|
||||
|
||||
sync_allowed_latches check(
|
||||
latches, latches + sizeof(latches)/sizeof(*latches));
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_ad(!sync_check_iterate(
|
||||
sync_allowed_latches(latches,
|
||||
latches + UT_ARR_SIZE(latches))));
|
||||
|
||||
if (log_sys->check_flush_or_checkpoint) {
|
||||
|
||||
log_check_margins();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
|
||||
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
|
||||
@@ -84,10 +84,10 @@ sync_check_find(latch_level_t level);
|
||||
|
||||
/** Checks that the level array for the current thread is empty.
|
||||
Terminate iteration if the functor returns true.
|
||||
@param[in,out] functor called for each element.
|
||||
@return true if the functor returns true */
|
||||
@param[in] functor called for each element.
|
||||
@return true if the functor returns true for any element */
|
||||
bool
|
||||
sync_check_iterate(sync_check_functor_t& functor);
|
||||
sync_check_iterate(const sync_check_functor_t& functor);
|
||||
|
||||
/** Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
|
||||
because the debug mutex is also acquired in sync0arr while holding the OS
|
||||
|
||||
@@ -1078,108 +1078,43 @@ struct latch_t {
|
||||
|
||||
/** Subclass this to iterate over a thread's acquired latch levels. */
|
||||
struct sync_check_functor_t {
|
||||
virtual ~sync_check_functor_t() { }
|
||||
virtual bool operator()(const latch_level_t) = 0;
|
||||
virtual bool result() const = 0;
|
||||
virtual bool operator()(const latch_level_t) const = 0;
|
||||
};
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** Functor to check whether the calling thread owns the btr search mutex. */
|
||||
struct btrsea_sync_check : public sync_check_functor_t {
|
||||
|
||||
/** Constructor
|
||||
@param[in] has_search_latch true if owns the latch */
|
||||
explicit btrsea_sync_check(bool has_search_latch)
|
||||
:
|
||||
m_result(),
|
||||
m_has_search_latch(has_search_latch) { }
|
||||
|
||||
/** Destructor */
|
||||
virtual ~btrsea_sync_check() { }
|
||||
|
||||
/** Called for every latch owned by the calling thread.
|
||||
@param[in] level Level of the existing latch
|
||||
@return true if the predicate check is successful */
|
||||
virtual bool operator()(const latch_level_t level)
|
||||
/** Check that no latch is being held.
|
||||
@tparam some_allowed whether some latches are allowed to be held */
|
||||
template<bool some_allowed = false>
|
||||
struct sync_checker : public sync_check_functor_t
|
||||
{
|
||||
/* If calling thread doesn't hold search latch then
|
||||
check if there are latch level exception provided. */
|
||||
|
||||
if (!m_has_search_latch
|
||||
&& (level != SYNC_SEARCH_SYS
|
||||
&& level != SYNC_FTS_CACHE)) {
|
||||
|
||||
m_result = true;
|
||||
|
||||
return(m_result);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
/** @return result from the check */
|
||||
virtual bool result() const
|
||||
{
|
||||
return(m_result);
|
||||
}
|
||||
|
||||
private:
|
||||
/** True if all OK */
|
||||
bool m_result;
|
||||
|
||||
/** If the caller owns the search latch */
|
||||
const bool m_has_search_latch;
|
||||
};
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** Functor to check for dictionay latching constraints. */
|
||||
struct dict_sync_check : public sync_check_functor_t {
|
||||
|
||||
/** Constructor
|
||||
@param[in] dict_mutex_allow true if the dict mutex
|
||||
is allowed */
|
||||
explicit dict_sync_check(bool dict_mutex_allowed)
|
||||
:
|
||||
m_result(),
|
||||
m_dict_mutex_allowed(dict_mutex_allowed) { }
|
||||
|
||||
/** Destructor */
|
||||
virtual ~dict_sync_check() { }
|
||||
|
||||
/** Check the latching constraints
|
||||
@param[in] level The level held by the thread */
|
||||
virtual bool operator()(const latch_level_t level)
|
||||
@param[in] level The level held by the thread
|
||||
@return whether a latch violation was detected */
|
||||
bool operator()(const latch_level_t level) const
|
||||
{
|
||||
if (!m_dict_mutex_allowed
|
||||
|| (level != SYNC_DICT
|
||||
&& level != SYNC_DICT_OPERATION
|
||||
&& level != SYNC_FTS_CACHE
|
||||
/* This only happens in recv_apply_hashed_log_recs. */
|
||||
&& level != SYNC_RECV_WRITER
|
||||
&& level != SYNC_NO_ORDER_CHECK)) {
|
||||
|
||||
m_result = true;
|
||||
if (some_allowed) {
|
||||
switch (level) {
|
||||
case SYNC_RECV_WRITER:
|
||||
/* This only happens in
|
||||
recv_apply_hashed_log_recs. */
|
||||
case SYNC_DICT:
|
||||
case SYNC_DICT_OPERATION:
|
||||
case SYNC_FTS_CACHE:
|
||||
case SYNC_NO_ORDER_CHECK:
|
||||
return(false);
|
||||
default:
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
/** @return the result of the check */
|
||||
virtual bool result() const
|
||||
{
|
||||
return(m_result);
|
||||
}
|
||||
|
||||
private:
|
||||
/** True if all OK */
|
||||
bool m_result;
|
||||
|
||||
/** True if it is OK to hold the dict mutex */
|
||||
const bool m_dict_mutex_allowed;
|
||||
};
|
||||
|
||||
/** The strict latch checker (no InnoDB latches may be held) */
|
||||
typedef struct sync_checker<false> sync_check;
|
||||
/** The sloppy latch checker (can hold InnoDB dictionary or SQL latches) */
|
||||
typedef struct sync_checker<true> dict_sync_check;
|
||||
|
||||
/** Functor to check for given latching constraints. */
|
||||
struct sync_allowed_latches : public sync_check_functor_t {
|
||||
|
||||
@@ -1189,9 +1124,7 @@ struct sync_allowed_latches : public sync_check_functor_t {
|
||||
sync_allowed_latches(
|
||||
const latch_level_t* from,
|
||||
const latch_level_t* to)
|
||||
:
|
||||
m_result(),
|
||||
m_latches(from, to) { }
|
||||
: begin(from), end(to) { }
|
||||
|
||||
/** Checks whether the given latch_t violates the latch constraint.
|
||||
This object maintains a list of allowed latch levels, and if the given
|
||||
@@ -1199,41 +1132,17 @@ struct sync_allowed_latches : public sync_check_functor_t {
|
||||
then it is a violation.
|
||||
|
||||
@param[in] latch The latch level to check
|
||||
@return true if there is a latch ordering violation */
|
||||
virtual bool operator()(const latch_level_t level)
|
||||
@return true if there is a latch violation */
|
||||
bool operator()(const latch_level_t level) const
|
||||
{
|
||||
for (latches_t::const_iterator it = m_latches.begin();
|
||||
it != m_latches.end();
|
||||
++it) {
|
||||
|
||||
if (level == *it) {
|
||||
|
||||
m_result = false;
|
||||
|
||||
/* No violation */
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/** @return the result of the check */
|
||||
virtual bool result() const
|
||||
{
|
||||
return(m_result);
|
||||
return(std::find(begin, end, level) == end);
|
||||
}
|
||||
|
||||
private:
|
||||
/** Save the result of validation check here
|
||||
True if all OK */
|
||||
bool m_result;
|
||||
|
||||
typedef std::vector<latch_level_t, ut_allocator<latch_level_t> >
|
||||
latches_t;
|
||||
|
||||
/** List of latch levels that are allowed to be held */
|
||||
latches_t m_latches;
|
||||
/** First element in an array of allowed latch levels */
|
||||
const latch_level_t* const begin;
|
||||
/** First element after the end of the array of allowed latch levels */
|
||||
const latch_level_t* const end;
|
||||
};
|
||||
|
||||
/** Get the latch id from a latch name.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 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
|
||||
@@ -162,10 +163,6 @@ struct i_s_trx_row_t {
|
||||
/*!< check_foreigns in trx_t */
|
||||
const char* trx_foreign_key_error;
|
||||
/*!< detailed_error in trx_t */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ibool trx_has_search_latch;
|
||||
/*!< has_search_latch in trx_t */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ulint trx_is_read_only;
|
||||
/*!< trx_t::read_only */
|
||||
ulint trx_is_autocommit_non_locking;
|
||||
|
||||
@@ -58,15 +58,6 @@ class FlushObserver;
|
||||
/** Dummy session used currently in MySQL interface */
|
||||
extern sess_t* trx_dummy_sess;
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/** Assert that the transaction is not holding the adaptive hash index latch.
|
||||
@param[in] trx transaction */
|
||||
# define trx_assert_no_search_latch(trx) \
|
||||
ut_ad(!trx->has_search_latch)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define trx_assert_no_search_latch(trx)
|
||||
#endif
|
||||
|
||||
/** Set flush observer for the transaction
|
||||
@param[in/out] trx transaction struct
|
||||
@param[in] observer flush observer */
|
||||
@@ -1072,11 +1063,6 @@ struct trx_t {
|
||||
flush the log in
|
||||
trx_commit_complete_for_mysql() */
|
||||
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
bool has_search_latch;
|
||||
/*!< TRUE if this trx has latched the
|
||||
search system latch in S-mode */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
trx_dict_op_t dict_operation; /**< @see enum trx_dict_op_t */
|
||||
|
||||
/* Fields protected by the srv_conc_mutex. */
|
||||
@@ -1508,17 +1494,11 @@ private:
|
||||
}
|
||||
|
||||
/* Avoid excessive mutex acquire/release */
|
||||
if (++trx->in_depth > 1) {
|
||||
if (trx->in_depth++) {
|
||||
/* The transaction is already inside InnoDB. */
|
||||
ut_ad(trx->in_depth > 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only the owning thread should release the latch. */
|
||||
|
||||
ut_ad(trx->in_depth == 1);
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
trx_mutex_enter(trx);
|
||||
|
||||
wait(trx);
|
||||
@@ -1543,16 +1523,10 @@ private:
|
||||
|
||||
ut_ad(trx->in_depth > 0);
|
||||
|
||||
if (--trx->in_depth > 0) {
|
||||
ut_ad(trx->in_depth);
|
||||
if (--trx->in_depth) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only the owning thread should release the latch. */
|
||||
|
||||
ut_ad(trx->in_depth == 0);
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
trx_mutex_enter(trx);
|
||||
|
||||
ut_ad((trx->in_innodb & TRX_FORCE_ROLLBACK_MASK) > 0);
|
||||
|
||||
@@ -2231,16 +2231,7 @@ stop_for_a_while:
|
||||
btr_pcur_store_position(&(plan->pcur), &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(true);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
err = DB_SUCCESS;
|
||||
goto func_exit;
|
||||
@@ -2258,14 +2249,7 @@ commit_mtr_for_a_while:
|
||||
mtr_commit(&mtr);
|
||||
|
||||
mtr_has_extra_clust_latch = FALSE;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_sync_check check(true);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
ut_ad(!sync_check_iterate(dict_sync_check()));
|
||||
|
||||
goto table_loop;
|
||||
|
||||
@@ -2280,20 +2264,13 @@ lock_wait_or_error:
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_sync_check check(true);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
func_exit:
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (search_latch_locked) {
|
||||
btr_search_s_unlock(index);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(dict_sync_check()));
|
||||
|
||||
if (heap != NULL) {
|
||||
mem_heap_free(heap);
|
||||
@@ -3041,7 +3018,6 @@ row_sel_store_mysql_field_func(
|
||||
mem_heap_t* heap;
|
||||
/* Copy an externally stored field to a temporary heap */
|
||||
|
||||
trx_assert_no_search_latch(prebuilt->trx);
|
||||
ut_ad(field_no == templ->clust_rec_field_no);
|
||||
ut_ad(templ->type != DATA_POINT);
|
||||
|
||||
@@ -3928,11 +3904,7 @@ row_sel_try_search_shortcut_for_mysql(
|
||||
ut_ad(!prebuilt->templ_contains_blob);
|
||||
|
||||
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
|
||||
BTR_SEARCH_LEAF, pcur,
|
||||
(trx->has_search_latch)
|
||||
? RW_S_LATCH
|
||||
: 0,
|
||||
mtr);
|
||||
BTR_SEARCH_LEAF, pcur, RW_S_LATCH, mtr);
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
if (!page_rec_is_user_rec(rec)) {
|
||||
@@ -4189,14 +4161,7 @@ row_search_mvcc(
|
||||
DBUG_RETURN(DB_END_OF_INDEX);
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
if (dict_table_is_discarded(prebuilt->table)) {
|
||||
|
||||
@@ -4221,8 +4186,6 @@ row_search_mvcc(
|
||||
&& (prebuilt->read_just_key
|
||||
|| prebuilt->m_read_virtual_key);
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
/* Reset the new record lock info if srv_locks_unsafe_for_binlog
|
||||
is set or session is using a READ COMMITED isolation level. Then
|
||||
we are able to remove the record locks set here on an individual
|
||||
@@ -4377,9 +4340,7 @@ row_search_mvcc(
|
||||
and if we try that, we can deadlock on the adaptive
|
||||
hash index semaphore! */
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
rw_lock_s_lock(btr_get_search_latch(index));
|
||||
trx->has_search_latch = true;
|
||||
|
||||
switch (row_sel_try_search_shortcut_for_mysql(
|
||||
&rec, prebuilt, &offsets, &heap,
|
||||
@@ -4434,7 +4395,6 @@ row_search_mvcc(
|
||||
err = DB_SUCCESS;
|
||||
|
||||
rw_lock_s_unlock(btr_get_search_latch(index));
|
||||
trx->has_search_latch = false;
|
||||
|
||||
goto func_exit;
|
||||
|
||||
@@ -4445,7 +4405,6 @@ row_search_mvcc(
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
|
||||
rw_lock_s_unlock(btr_get_search_latch(index));
|
||||
trx->has_search_latch = false;
|
||||
|
||||
/* NOTE that we do NOT store the cursor
|
||||
position */
|
||||
@@ -4463,7 +4422,6 @@ row_search_mvcc(
|
||||
mtr_start(&mtr);
|
||||
|
||||
rw_lock_s_unlock(btr_get_search_latch(index));
|
||||
trx->has_search_latch = false;
|
||||
}
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
@@ -4471,8 +4429,6 @@ row_search_mvcc(
|
||||
/*-------------------------------------------------------------*/
|
||||
/* PHASE 3: Open or restore index cursor position */
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
spatial_search = dict_index_is_spatial(index)
|
||||
&& mode >= PAGE_CUR_CONTAIN;
|
||||
|
||||
@@ -5777,15 +5733,7 @@ func_exit:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
DEBUG_SYNC_C("innodb_row_search_for_mysql_exit");
|
||||
|
||||
|
||||
@@ -197,11 +197,6 @@ srv_conc_enter_innodb_with_atomics(
|
||||
(void) my_atomic_addlint(
|
||||
&srv_conc.n_waiting, 1);
|
||||
|
||||
/* Release possible search system latch this
|
||||
thread has */
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK);
|
||||
|
||||
notified_mysql = TRUE;
|
||||
@@ -257,15 +252,7 @@ srv_conc_enter_innodb(
|
||||
{
|
||||
trx_t* trx = prebuilt->trx;
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
srv_conc_enter_innodb_with_atomics(trx);
|
||||
}
|
||||
@@ -279,15 +266,7 @@ srv_conc_force_enter_innodb(
|
||||
trx_t* trx) /*!< in: transaction object associated with the
|
||||
thread */
|
||||
{
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
|
||||
if (!srv_thread_concurrency) {
|
||||
|
||||
@@ -320,15 +299,7 @@ srv_conc_force_exit_innodb(
|
||||
|
||||
srv_conc_exit_innodb_with_atomics(trx);
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# ifdef UNIV_DEBUG
|
||||
{
|
||||
btrsea_sync_check check(trx->has_search_latch);
|
||||
|
||||
ut_ad(!sync_check_iterate(check));
|
||||
}
|
||||
# endif /* UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
|
||||
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
|
||||
@@ -298,29 +298,23 @@ struct LatchDebug {
|
||||
}
|
||||
|
||||
/** Iterate over a thread's latches.
|
||||
@param[in,out] functor The callback
|
||||
@param[in] functor The callback
|
||||
@return true if the functor returns true. */
|
||||
bool for_each(sync_check_functor_t& functor)
|
||||
bool for_each(const sync_check_functor_t& functor)
|
||||
UNIV_NOTHROW
|
||||
{
|
||||
const Latches* latches = thread_latches();
|
||||
|
||||
if (latches == 0) {
|
||||
return(functor.result());
|
||||
}
|
||||
|
||||
if (const Latches* latches = thread_latches()) {
|
||||
Latches::const_iterator end = latches->end();
|
||||
|
||||
for (Latches::const_iterator it = latches->begin();
|
||||
it != end;
|
||||
++it) {
|
||||
it != end; ++it) {
|
||||
|
||||
if (functor(it->m_level)) {
|
||||
break;
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(functor.result());
|
||||
return(false);
|
||||
}
|
||||
|
||||
/** Removes a latch from the thread level array if it is found there.
|
||||
@@ -1215,13 +1209,12 @@ sync_check_find(latch_level_t level)
|
||||
|
||||
/** Iterate over the thread's latches.
|
||||
@param[in,out] functor called for each element.
|
||||
@return false if the sync debug hasn't been initialised
|
||||
@return the value returned by the functor */
|
||||
@return true if the functor returns true for any element */
|
||||
bool
|
||||
sync_check_iterate(sync_check_functor_t& functor)
|
||||
sync_check_iterate(const sync_check_functor_t& functor)
|
||||
{
|
||||
if (LatchDebug::instance() != NULL) {
|
||||
return(LatchDebug::instance()->for_each(functor));
|
||||
if (LatchDebug* debug = LatchDebug::instance()) {
|
||||
return(debug->for_each(functor));
|
||||
}
|
||||
|
||||
return(false);
|
||||
|
||||
@@ -589,10 +589,6 @@ thd_done:
|
||||
row->trx_foreign_key_error = NULL;
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
row->trx_has_search_latch = (ibool) trx->has_search_latch;
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
row->trx_is_read_only = trx->read_only;
|
||||
|
||||
row->trx_is_autocommit_non_locking = trx_is_autocommit_non_locking(trx);
|
||||
|
||||
@@ -272,8 +272,6 @@ struct TrxFactory {
|
||||
|
||||
ut_a(trx->lock.wait_lock == NULL);
|
||||
ut_a(trx->lock.wait_thr == NULL);
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
if (trx->lock.lock_heap != NULL) {
|
||||
@@ -341,9 +339,6 @@ struct TrxFactory {
|
||||
|
||||
ut_a(trx->lock.wait_thr == NULL);
|
||||
ut_a(trx->lock.wait_lock == NULL);
|
||||
|
||||
trx_assert_no_search_latch(trx);
|
||||
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
|
||||
@@ -2413,13 +2408,6 @@ state_ok:
|
||||
(ulong) n_rec_locks);
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (trx->has_search_latch) {
|
||||
newline = TRUE;
|
||||
fputs(", holds adaptive hash latch", f);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
if (trx->undo_no != 0) {
|
||||
newline = TRUE;
|
||||
fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no);
|
||||
@@ -2551,11 +2539,6 @@ state_ok:
|
||||
fprintf(f, "que state %lu ", (ulong) trx->lock.que_state);
|
||||
}
|
||||
|
||||
if (trx->has_search_latch) {
|
||||
newline = TRUE;
|
||||
fputs(", holds adaptive hash latch", f);
|
||||
}
|
||||
|
||||
if (trx->undo_no != 0) {
|
||||
newline = TRUE;
|
||||
fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no);
|
||||
|
||||
Reference in New Issue
Block a user