Commit 5bd994b0 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24811 Assertion find(table) failed with innodb_evict_tables_on_commit_debug

This is a backport of commit 18535a40
from 10.6.

lock_release(): Implement innodb_evict_tables_on_commit_debug.
Before releasing any locks, collect the identifiers of tables to
be evicted. After releasing all locks, look up for the tables and
evict them if it is safe to do so.

trx_commit_in_memory(): Invoke trx_update_mod_tables_timestamp()
before lock_release(), so that our locks will protect the tables
from being evicted.
parent ddbc6126
......@@ -4263,6 +4263,19 @@ lock_check_dict_lock(
and release possible other transactions waiting because of these locks. */
void lock_release(trx_t* trx)
{
#ifdef UNIV_DEBUG
std::set<table_id_t> to_evict;
if (innodb_evict_tables_on_commit_debug && !trx->is_recovered)
# if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */
if (!mutex_own(&dict_sys->mutex))
# else /* this would be more proper way to do it */
if (!trx->dict_operation_lock_mode && !trx->dict_operation)
# endif
for (trx_mod_tables_t::const_iterator it= trx->mod_tables.begin();
it != trx->mod_tables.end(); ++it)
if (!it->first->is_temporary())
to_evict.insert(it->first->id);
#endif
ulint count = 0;
trx_id_t max_trx_id = trx_sys.get_max_trx_id();
......@@ -4311,6 +4324,26 @@ void lock_release(trx_t* trx)
}
lock_mutex_exit();
#ifdef UNIV_DEBUG
if (to_evict.empty()) {
return;
}
mutex_enter(&dict_sys->mutex);
lock_mutex_enter();
for (std::set<table_id_t>::const_iterator i = to_evict.begin();
i != to_evict.end(); ++i) {
if (dict_table_t *table = dict_table_open_on_id(
*i, TRUE, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED)) {
if (!table->get_ref_count()
&& !UT_LIST_GET_LEN(table->locks)) {
dict_table_remove_from_cache_low(table, true);
}
}
}
lock_mutex_exit();
mutex_exit(&dict_sys->mutex);
#endif
}
/* True if a lock mode is S or X */
......
......@@ -1276,22 +1276,6 @@ trx_update_mod_tables_timestamp(
const time_t now = time(NULL);
trx_mod_tables_t::const_iterator end = trx->mod_tables.end();
#ifdef UNIV_DEBUG
# if MYSQL_VERSION_ID >= 100405
# define dict_sys_mutex dict_sys.mutex
# else
# define dict_sys_mutex dict_sys->mutex
# endif
const bool preserve_tables = !innodb_evict_tables_on_commit_debug
|| trx->is_recovered /* avoid trouble with XA recovery */
# if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */
|| mutex_own(&dict_sys_mutex)
# else /* this would be more proper way to do it */
|| trx->dict_operation_lock_mode || trx->dict_operation
# endif
;
#endif
for (trx_mod_tables_t::const_iterator it = trx->mod_tables.begin();
it != end;
......@@ -1307,30 +1291,6 @@ trx_update_mod_tables_timestamp(
intrusive. */
dict_table_t* table = it->first;
table->update_time = now;
#ifdef UNIV_DEBUG
if (preserve_tables || table->get_ref_count()
|| UT_LIST_GET_LEN(table->locks)) {
/* do not evict when committing DDL operations
or if some other transaction is holding the
table handle */
continue;
}
/* recheck while holding the mutex that blocks
table->acquire() */
mutex_enter(&dict_sys_mutex);
mutex_enter(&lock_sys.mutex);
const bool do_evict = !table->get_ref_count()
&& !UT_LIST_GET_LEN(table->locks);
mutex_exit(&lock_sys.mutex);
if (do_evict) {
# if MYSQL_VERSION_ID >= 100405
dict_sys.remove(table, true);
# else
dict_table_remove_from_cache_low(table, true);
# endif
}
mutex_exit(&dict_sys_mutex);
#endif
}
trx->mod_tables.clear();
......@@ -1398,16 +1358,10 @@ trx_commit_in_memory(
while (UNIV_UNLIKELY(trx->is_referenced())) {
ut_delay(srv_spin_wait_delay);
}
trx->release_locks();
trx->id = 0;
} else {
ut_ad(trx->read_only || !trx->rsegs.m_redo.rseg);
trx->release_locks();
}
DEBUG_SYNC_C("after_trx_committed_in_memory");
if (trx->read_only || !trx->rsegs.m_redo.rseg) {
MONITOR_INC(MONITOR_TRX_RO_COMMIT);
} else {
......@@ -1415,6 +1369,10 @@ trx_commit_in_memory(
MONITOR_INC(MONITOR_TRX_RW_COMMIT);
trx->is_recovered = false;
}
trx->release_locks();
trx->id = 0;
DEBUG_SYNC_C("after_trx_committed_in_memory");
}
ut_ad(!trx->rsegs.m_redo.undo);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment