Commit 2e08b6d7 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24258 preparation: Remove dict_sys.freeze() and unfreeze()

This will essentially make dict_sys.latch a mutex
(it is only acquired in exclusive mode).

The subsequent commit will merge dict_sys.mutex into dict_sys.latch
and reintroduce dict_sys.freeze() for those cases where we currently
acquire only dict_sys.latch but not dict_sys.mutex. The case where
both are acquired will be mapped to dict_sys.lock().

i_s_sys_tables_fill_table_stats(): Invoke dict_sys.prevent_eviction()
and the new function dict_sys.allow_eviction() to avoid table eviction
while a row in INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS is being
produced.

Reviewed by: Thirunarayanan Balathandayuthapani
parent 4362ed1b
...@@ -5095,9 +5095,8 @@ i_s_sys_tables_fill_table_stats( ...@@ -5095,9 +5095,8 @@ i_s_sys_tables_fill_table_stats(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
dict_sys.freeze(); mtr.start();
dict_sys.mutex_lock(); dict_sys.lock(SRW_LOCK_CALL);
mtr_start(&mtr);
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables);
...@@ -5110,33 +5109,36 @@ i_s_sys_tables_fill_table_stats( ...@@ -5110,33 +5109,36 @@ i_s_sys_tables_fill_table_stats(
this SYS_TABLES record */ this SYS_TABLES record */
err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec); err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec);
ulint ref_count = table_rec ? table_rec->get_ref_count() : 0; if (UNIV_LIKELY(!err_msg)) {
dict_sys.mutex_unlock(); bool evictable = dict_sys.prevent_eviction(table_rec);
ulint ref_count = table_rec->get_ref_count();
if (table_rec != NULL) { dict_sys.unlock();
ut_ad(err_msg == NULL);
i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count, i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count,
tables->table); tables->table);
if (!evictable) {
table_rec = nullptr;
}
} else { } else {
ut_ad(err_msg != NULL); ut_ad(!table_rec);
dict_sys.unlock();
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_CANT_FIND_SYSTEM_REC, "%s", ER_CANT_FIND_SYSTEM_REC, "%s",
err_msg); err_msg);
} }
dict_sys.unfreeze();
/* Get the next record */ /* Get the next record */
dict_sys.freeze(); mtr.start();
dict_sys.mutex_lock(); dict_sys.lock(SRW_LOCK_CALL);
if (table_rec) {
dict_sys.allow_eviction(table_rec);
}
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr); rec = dict_getnext_system(&pcur, &mtr);
} }
mtr_commit(&mtr); mtr.commit();
dict_sys.mutex_unlock(); dict_sys.unlock();
dict_sys.unfreeze();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -1527,17 +1527,28 @@ class dict_sys_t ...@@ -1527,17 +1527,28 @@ class dict_sys_t
} }
#endif #endif
/** Move a table to the non-LRU list from the LRU list. */ /** Move a table to the non-LRU list from the LRU list.
void prevent_eviction(dict_table_t *table) @return whether the table was evictable */
bool prevent_eviction(dict_table_t *table)
{ {
ut_ad(find(table)); ut_ad(find(table));
if (table->can_be_evicted) if (!table->can_be_evicted)
{ return false;
table->can_be_evicted= false; table->can_be_evicted= false;
UT_LIST_REMOVE(table_LRU, table); UT_LIST_REMOVE(table_LRU, table);
UT_LIST_ADD_LAST(table_non_LRU, table); UT_LIST_ADD_LAST(table_non_LRU, table);
return true;
} }
/** Move a table from the non-LRU list to the LRU list. */
void allow_eviction(dict_table_t *table)
{
ut_ad(find(table));
ut_ad(!table->can_be_evicted);
table->can_be_evicted= true;
UT_LIST_REMOVE(table_non_LRU, table);
UT_LIST_ADD_LAST(table_LRU, table);
} }
/** Acquire a reference to a cached table. */ /** Acquire a reference to a cached table. */
inline void acquire(dict_table_t *table); inline void acquire(dict_table_t *table);
...@@ -1582,11 +1593,6 @@ class dict_sys_t ...@@ -1582,11 +1593,6 @@ class dict_sys_t
latch.wr_unlock(); latch.wr_unlock();
} }
/** Prevent modifications of the data dictionary */
void freeze() { latch.rd_lock(SRW_LOCK_CALL); ut_ad(!latch_ex); }
/** Allow modifications of the data dictionary */
void unfreeze() { ut_ad(!latch_ex); latch.rd_unlock(); }
/** Estimate the used memory occupied by the data dictionary /** Estimate the used memory occupied by the data dictionary
table and index objects. table and index objects.
@return number of bytes occupied */ @return number of bytes occupied */
......
...@@ -162,7 +162,7 @@ wsrep_row_upd_index_is_foreign( ...@@ -162,7 +162,7 @@ wsrep_row_upd_index_is_foreign(
/* No MDL protects dereferencing the members of table->foreign_set. */ /* No MDL protects dereferencing the members of table->foreign_set. */
const bool no_lock= !trx->dict_operation_lock_mode; const bool no_lock= !trx->dict_operation_lock_mode;
if (no_lock) if (no_lock)
dict_sys.freeze(); dict_sys.mutex_lock();
auto end= table->foreign_set.end(); auto end= table->foreign_set.end();
const bool is_referenced= end != const bool is_referenced= end !=
...@@ -170,7 +170,7 @@ wsrep_row_upd_index_is_foreign( ...@@ -170,7 +170,7 @@ wsrep_row_upd_index_is_foreign(
[index](const dict_foreign_t* f) [index](const dict_foreign_t* f)
{return f->foreign_index == index;}); {return f->foreign_index == index;});
if (no_lock) if (no_lock)
dict_sys.unfreeze(); dict_sys.mutex_unlock();
return is_referenced; return is_referenced;
} }
......
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