Skip to content

Commit

Permalink
Cleanup: Access lower_case_table_names, tdc_size directly
Browse files Browse the repository at this point in the history
dict_sys_t::evict_table_LRU(): Replaces dict_make_room_in_cache() and
srv_master_evict_from_table_cache().

innobase_get_table_cache_size(): Replaced with direct read of tdc_size,
in dict_sys_t::evict_table_LRU().

innobase_get_lower_case_table_names(): Replaced with direct reads of
lower_case_table_names.
  • Loading branch information
dr-m committed May 21, 2021
1 parent 383f77c commit 9eb4ad5
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 149 deletions.
92 changes: 37 additions & 55 deletions storage/innobase/dict/dict0dict.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1248,14 +1248,10 @@ inline void dict_sys_t::add(dict_table_t* table)
ut_ad(dict_lru_validate());
}

/**********************************************************************//**
Test whether a table can be evicted from the LRU cache.
@return TRUE if table can be evicted. */
static
ibool
dict_table_can_be_evicted(
/*======================*/
dict_table_t* table) /*!< in: table to test */
/** Test whether a table can be evicted from dict_sys.table_LRU.
@param table table to be considered for eviction
@return whether the table can be evicted */
static bool dict_table_can_be_evicted(dict_table_t *table)
{
ut_d(dict_sys.assert_locked());
ut_a(table->can_be_evicted);
Expand All @@ -1269,25 +1265,26 @@ dict_table_can_be_evicted(
the table instance is in "use". */

if (lock_table_has_locks(table)) {
return(FALSE);
return false;
}

#ifdef BTR_CUR_HASH_ADAPT
/* We cannot really evict the table if adaptive hash
index entries are pointing to any of its indexes. */
for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
for (const dict_index_t* index
= dict_table_get_first_index(table);
index; index = dict_table_get_next_index(index)) {
if (index->n_ahi_pages()) {
return(FALSE);
return false;
}
}
#endif /* BTR_CUR_HASH_ADAPT */

return(TRUE);
ut_ad(!table->fts);
return true;
}

return(FALSE);
return false;
}

#ifdef BTR_CUR_HASH_ADAPT
Expand Down Expand Up @@ -1354,64 +1351,49 @@ dict_index_t *dict_index_t::clone_if_needed()
}
#endif /* BTR_CUR_HASH_ADAPT */

/**********************************************************************//**
Make room in the table cache by evicting an unused table. The unused table
should not be part of FK relationship and currently not used in any user
transaction. There is no guarantee that it will remove a table.
@return number of tables evicted. If the number of tables in the dict_LRU
is less than max_tables it will not do anything. */
ulint
dict_make_room_in_cache(
/*====================*/
ulint max_tables, /*!< in: max tables allowed in cache */
ulint pct_check) /*!< in: max percent to check */
/** Evict unused, unlocked tables from table_LRU.
@param half whether to consider half the tables only (instead of all)
@return number of tables evicted */
ulint dict_sys_t::evict_table_LRU(bool half)
{
ulint i;
ulint len;
dict_table_t* table;
ulint check_up_to;
ulint n_evicted = 0;
#ifdef MYSQL_DYNAMIC_PLUGIN
constexpr ulint max_tables = 400;
#else
extern ulong tdc_size;
const ulint max_tables = tdc_size;
#endif
ulint n_evicted = 0;

ut_a(pct_check > 0);
ut_a(pct_check <= 100);
ut_d(dict_sys.assert_locked());
lock(SRW_LOCK_CALL);
ut_ad(dict_lru_validate());

i = len = UT_LIST_GET_LEN(dict_sys.table_LRU);
const ulint len = UT_LIST_GET_LEN(table_LRU);

if (len < max_tables) {
return(0);
func_exit:
unlock();
return(n_evicted);
}

check_up_to = len - ((len * pct_check) / 100);

/* Check for overflow */
ut_a(i == 0 || check_up_to <= i);
const ulint check_up_to = half ? len / 2 : 0;
ulint i = len;

/* Find a suitable candidate to evict from the cache. Don't scan the
entire LRU list. Only scan pct_check list entries. */

for (table = UT_LIST_GET_LAST(dict_sys.table_LRU);
table != NULL
&& i > check_up_to
&& (len - n_evicted) > max_tables;
--i) {

dict_table_t* prev_table;

prev_table = UT_LIST_GET_PREV(table_LRU, table);
for (dict_table_t *table = UT_LIST_GET_LAST(table_LRU);
table && i > check_up_to && (len - n_evicted) > max_tables; --i) {
dict_table_t* prev_table = UT_LIST_GET_PREV(table_LRU, table);

if (dict_table_can_be_evicted(table)) {
ut_ad(!table->fts);
dict_sys.remove(table, true);

remove(table, true);
++n_evicted;
}

table = prev_table;
}

return(n_evicted);
goto func_exit;
}

/** Looks for an index with the given id given a table instance.
Expand Down Expand Up @@ -3411,7 +3393,7 @@ dict_get_referenced_table(
/* Values; 0 = Store and compare as given; case sensitive
1 = Store and compare in lower; case insensitive
2 = Store as given, compare in lower; case semi-sensitive */
if (innobase_get_lower_case_table_names() == 2) {
if (lower_case_table_names == 2) {
innobase_casedn_str(ref);
*table = dict_table_get_low(ref);
memcpy(ref, database_name, database_name_len);
Expand All @@ -3420,7 +3402,7 @@ dict_get_referenced_table(

} else {
#ifndef _WIN32
if (innobase_get_lower_case_table_names() == 1) {
if (lower_case_table_names == 1) {
innobase_casedn_str(ref);
}
#else
Expand Down
3 changes: 1 addition & 2 deletions storage/innobase/dict/dict0load.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3181,8 +3181,7 @@ dict_load_foreigns(
goto next_rec;
}

if (innobase_get_lower_case_table_names() != 2
&& memcmp(field, table_name, len)) {
if (lower_case_table_names != 2 && memcmp(field, table_name, len)) {
goto next_rec;
}

Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/dict/dict0mem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ dict_mem_foreign_table_name_lookup_set(
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{
if (innobase_get_lower_case_table_names() == 2) {
if (lower_case_table_names == 2) {
if (do_alloc) {
ulint len;

Expand Down Expand Up @@ -863,7 +863,7 @@ dict_mem_referenced_table_name_lookup_set(
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{
if (innobase_get_lower_case_table_names() == 2) {
if (lower_case_table_names == 2) {
if (do_alloc) {
ulint len;

Expand Down
33 changes: 3 additions & 30 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ void close_thread_tables(THD* thd);

#ifdef MYSQL_DYNAMIC_PLUGIN
#define tc_size 400
#define tdc_size 400
#endif

#include <mysql/plugin.h>
Expand Down Expand Up @@ -2362,31 +2361,6 @@ innobase_get_stmt_unsafe(
return NULL;
}

/**********************************************************************//**
Get the current setting of the tdc_size global parameter. We do
a dirty read because for one there is no synchronization object and
secondly there is little harm in doing so even if we get a torn read.
@return value of tdc_size */
ulint
innobase_get_table_cache_size(void)
/*===============================*/
{
return(tdc_size);
}

/**********************************************************************//**
Get the current setting of the lower_case_table_names global parameter from
mysqld.cc. We do a dirty read because for one there is no synchronization
object and secondly there is little harm in doing so even if we get a torn
read.
@return value of lower_case_table_names */
ulint
innobase_get_lower_case_table_names(void)
/*=====================================*/
{
return(lower_case_table_names);
}

/**
Test a file path whether it is same as mysql data directory path.

Expand Down Expand Up @@ -6088,7 +6062,7 @@ ha_innobase::open_dict_table(
sensitive platform in Windows, we might need to
check the existence of table name without lower
case in the system table. */
if (innobase_get_lower_case_table_names() == 1) {
if (lower_case_table_names == 1) {
char par_case_name[FN_REFLEN];

#ifndef _WIN32
Expand Down Expand Up @@ -13352,8 +13326,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom)

err = row_drop_table_for_mysql(norm_name, trx, sqlcom);

if (err == DB_TABLE_NOT_FOUND
&& innobase_get_lower_case_table_names() == 1) {
if (err == DB_TABLE_NOT_FOUND && lower_case_table_names == 1) {
char* is_part = is_partition(norm_name);

if (is_part) {
Expand Down Expand Up @@ -13451,7 +13424,7 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from,

if (error != DB_SUCCESS) {
if (error == DB_TABLE_NOT_FOUND
&& innobase_get_lower_case_table_names() == 1) {
&& lower_case_table_names == 1) {
char* is_part = is_partition(norm_from);

if (is_part) {
Expand Down
15 changes: 5 additions & 10 deletions storage/innobase/include/dict0dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,16 +942,6 @@ dict_index_find_on_id_low(
/*======================*/
index_id_t id) /*!< in: index id */
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Make room in the table cache by evicting an unused table. The unused table
should not be part of FK relationship and currently not used in any user
transaction. There is no guarantee that it will remove a table.
@return number of tables evicted. */
ulint
dict_make_room_in_cache(
/*====================*/
ulint max_tables, /*!< in: max tables allowed in cache */
ulint pct_check); /*!< in: max percent to check */

/** Adds an index to the dictionary cache, with possible indexing newly
added column.
Expand Down Expand Up @@ -1587,6 +1577,11 @@ class dict_sys_t
+ temp_id_hash.n_cells) * sizeof(hash_cell_t);
return size;
}

/** Evict unused, unlocked tables from table_LRU.
@param half whether to consider half the tables only (instead of all)
@return number of tables evicted */
ulint evict_table_LRU(bool half);
};

/** the data dictionary cache */
Expand Down
19 changes: 0 additions & 19 deletions storage/innobase/include/ha_prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,25 +257,6 @@ const char*
thd_innodb_tmpdir(
THD* thd);

/**********************************************************************//**
Get the current setting of the table_cache_size global parameter. We do
a dirty read because for one there is no synchronization object and
secondly there is little harm in doing so even if we get a torn read.
@return SQL statement string */
ulint
innobase_get_table_cache_size(void);
/*===============================*/

/**********************************************************************//**
Get the current setting of the lower_case_table_names global parameter from
mysqld.cc. We do a dirty read because for one there is no synchronization
object and secondly there is little harm in doing so even if we get a torn
read.
@return value of lower_case_table_names */
ulint
innobase_get_lower_case_table_names(void);
/*=====================================*/

/******************************************************************//**
compare two character string case insensitively according to their charset. */
int
Expand Down
11 changes: 4 additions & 7 deletions storage/innobase/row/row0mysql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3815,10 +3815,9 @@ row_rename_table_for_mysql(
is_part = strstr((char *)old_name, (char *)"#P#");
#endif /* __WIN__ */

/* MySQL partition engine hard codes the file name
separator as "#P#". The text case is fixed even if
lower_case_table_names is set to 1 or 2. This is true
for sub-partition names as well. InnoDB always
/* MariaDB partition engine hard codes the file name
separator as "#P#" and "#SP#". The text case is fixed even if
lower_case_table_names is set to 1 or 2. InnoDB always
normalises file names to lower case on Windows, this
can potentially cause problems when copying/moving
tables between platforms.
Expand All @@ -3832,9 +3831,7 @@ row_rename_table_for_mysql(
sensitive platform in Windows, we might need to
check the existence of table name without lowering
case them in the system table. */
if (!table &&
is_part &&
innobase_get_lower_case_table_names() == 1) {
if (!table && is_part && lower_case_table_names == 1) {
char par_case_name[MAX_FULL_NAME_LEN + 1];
#ifndef __WIN__
/* Check for the table using lower
Expand Down
26 changes: 2 additions & 24 deletions storage/innobase/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1487,27 +1487,6 @@ srv_sync_log_buffer_in_background(void)
}
}

/********************************************************************//**
Make room in the table cache by evicting an unused table.
@return number of tables evicted. */
static
ulint
srv_master_evict_from_table_cache(
/*==============================*/
ulint pct_check) /*!< in: max percent to check */
{
ulint n_tables_evicted = 0;

dict_sys_lock();

n_tables_evicted = dict_make_room_in_cache(
innobase_get_table_cache_size(), pct_check);

dict_sys_unlock();

return(n_tables_evicted);
}

/*********************************************************************//**
This function prints progress message every 60 seconds during server
shutdown, for any activities that master thread is pending on. */
Expand Down Expand Up @@ -1640,7 +1619,7 @@ srv_master_do_active_tasks(void)

if (cur_time % SRV_MASTER_DICT_LRU_INTERVAL == 0) {
srv_main_thread_op_info = "enforcing dict cache limit";
ulint n_evicted = srv_master_evict_from_table_cache(50);
ulint n_evicted = dict_sys.evict_table_LRU(true);
if (n_evicted != 0) {
MONITOR_INC_VALUE(
MONITOR_SRV_DICT_LRU_EVICT_COUNT_ACTIVE, n_evicted);
Expand Down Expand Up @@ -1694,8 +1673,7 @@ srv_master_do_idle_tasks(void)
}

srv_main_thread_op_info = "enforcing dict cache limit";
ulint n_evicted = srv_master_evict_from_table_cache(100);
if (n_evicted != 0) {
if (ulint n_evicted = dict_sys.evict_table_LRU(false)) {
MONITOR_INC_VALUE(
MONITOR_SRV_DICT_LRU_EVICT_COUNT_IDLE, n_evicted);
}
Expand Down

0 comments on commit 9eb4ad5

Please sign in to comment.