summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-07-30 11:15:54 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-07-30 11:15:54 +0300
commitc69286b73e4dec4d488fb2ad7a248a4905a5ec4b (patch)
treecf8a301cc58878afb531e1b1f3df34bd79cb5f3e
parent07674e6a741a82d2e30f9798f699209a6c34dfef (diff)
downloadmariadb-git-c69286b73e4dec4d488fb2ad7a248a4905a5ec4b.tar.gz
MDEV-24258 preparation: Remove dict_sys.freeze() and unfreeze()
With this change, dict_sys.latch will essentially become 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.
-rw-r--r--storage/innobase/handler/i_s.cc36
-rw-r--r--storage/innobase/include/dict0dict.h32
-rw-r--r--storage/innobase/row/row0upd.cc4
3 files changed, 40 insertions, 32 deletions
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 8d8ab582f05..3b2207beed5 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -5097,9 +5097,8 @@ i_s_sys_tables_fill_table_stats(
DBUG_RETURN(0);
}
- dict_sys.freeze();
- dict_sys.mutex_lock();
- mtr_start(&mtr);
+ mtr.start();
+ dict_sys.lock(SRW_LOCK_CALL);
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables);
@@ -5112,33 +5111,36 @@ i_s_sys_tables_fill_table_stats(
this SYS_TABLES record */
err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec);
- ulint ref_count = table_rec ? table_rec->get_ref_count() : 0;
- dict_sys.mutex_unlock();
-
- if (table_rec != NULL) {
- ut_ad(err_msg == NULL);
+ if (UNIV_LIKELY(!err_msg)) {
+ bool evictable = dict_sys.prevent_eviction(table_rec);
+ ulint ref_count = table_rec->get_ref_count();
+ dict_sys.unlock();
i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count,
tables->table);
+ if (!evictable) {
+ table_rec = nullptr;
+ }
} else {
- ut_ad(err_msg != NULL);
+ ut_ad(!table_rec);
+ dict_sys.unlock();
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_CANT_FIND_SYSTEM_REC, "%s",
err_msg);
}
- dict_sys.unfreeze();
-
/* Get the next record */
- dict_sys.freeze();
- dict_sys.mutex_lock();
+ mtr.start();
+ dict_sys.lock(SRW_LOCK_CALL);
+
+ if (table_rec) {
+ dict_sys.allow_eviction(table_rec);
+ }
- mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
}
- mtr_commit(&mtr);
- dict_sys.mutex_unlock();
- dict_sys.unfreeze();
+ mtr.commit();
+ dict_sys.unlock();
DBUG_RETURN(0);
}
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 3c0e93edc8f..6f5d2377b07 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1527,17 +1527,28 @@ public:
}
#endif
- /** Move a table to the non-LRU list from the LRU list. */
- void prevent_eviction(dict_table_t *table)
+ /** Move a table to the non-LRU list from the LRU list.
+ @return whether the table was evictable */
+ bool prevent_eviction(dict_table_t *table)
{
ut_ad(find(table));
- if (table->can_be_evicted)
- {
- table->can_be_evicted= false;
- UT_LIST_REMOVE(table_LRU, table);
- UT_LIST_ADD_LAST(table_non_LRU, table);
- }
+ if (!table->can_be_evicted)
+ return false;
+ table->can_be_evicted= false;
+ UT_LIST_REMOVE(table_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. */
inline void acquire(dict_table_t *table);
@@ -1582,11 +1593,6 @@ public:
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
table and index objects.
@return number of bytes occupied */
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index f10449b735b..41cae945c99 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -157,7 +157,7 @@ wsrep_row_upd_index_is_foreign(
/* No MDL protects dereferencing the members of table->foreign_set. */
const bool no_lock= !trx->dict_operation_lock_mode;
if (no_lock)
- dict_sys.freeze();
+ dict_sys.mutex_lock();
auto end= table->foreign_set.end();
const bool is_referenced= end !=
@@ -165,7 +165,7 @@ wsrep_row_upd_index_is_foreign(
[index](const dict_foreign_t* f)
{return f->foreign_index == index;});
if (no_lock)
- dict_sys.unfreeze();
+ dict_sys.mutex_unlock();
return is_referenced;
}