diff --git a/storage/innobase/dict/mem.cc b/storage/innobase/dict/mem.cc index b35b3cdfe50b..36894fbde5e0 100644 --- a/storage/innobase/dict/mem.cc +++ b/storage/innobase/dict/mem.cc @@ -35,6 +35,7 @@ this program; if not, write to the Free Software Foundation, Inc., other files in library. The code in this file is used to make a library for external tools. */ +#include #include #include "dict0dict.h" @@ -147,35 +148,36 @@ void dict_mem_table_free(dict_table_t *table) /*!< in: table */ } /** System databases */ -static std::string innobase_system_databases[] = { - "mysql/", "information_schema/", "performance_schema/", ""}; +static std::vector innobase_system_databases({ + "mysql/", "information_schema/", "performance_schema/" +}); /** Determines if a table is a system table @param[in] name table_name @return true if table is system table */ -static bool dict_mem_table_is_system(const std::string name) { +static bool dict_mem_table_is_system(const std::string &name) { /* Table has the following format: database/table and some system table are of the form SYS_* */ - if (name.find('/') != std::string::npos) { - size_t table_len = name.length(); - - std::string system_db = std::string(innobase_system_databases[0]); - int i = 0; + if (name.find('/') == std::string::npos) + return true; - while (system_db.compare("") != 0) { - size_t len = system_db.length(); + for (auto p : innobase_system_databases) { + if (name.length() > p.length() && name.compare(0, p.length(), p) == 0) + return true; + } - if (table_len > len && name.compare(0, len, system_db) == 0) { - return true; - } + return false; +} - system_db = std::string(innobase_system_databases[++i]); - } +void dict_add_system_prefix(const char *pfx) { + if (!pfx || !pfx[0]) + return; - return false; - } else { - return true; - } + std::string pfx_s = pfx; + if (pfx_s[pfx_s.size()-1] != '/') + pfx_s += '/'; + if (std::find(innobase_system_databases.begin(), innobase_system_databases.end(), pfx_s) == innobase_system_databases.end()) + innobase_system_databases.push_back(pfx_s); } /** Creates a table memory object. diff --git a/storage/innobase/dict/mem.h b/storage/innobase/dict/mem.h index afcf3a73407f..871081fdff55 100644 --- a/storage/innobase/dict/mem.h +++ b/storage/innobase/dict/mem.h @@ -91,4 +91,9 @@ const char *dict_add_col_name(const char *col_names, /*!< in: existing column ulint cols, /*!< in: number of existing columns */ const char *name, /*!< in: new column name */ mem_heap_t *heap); /*!< in: heap */ + +/** Add the prefix 'pfx' to the list of database names that count as + * system tables, rather than user tables, for the purposes of rows + * {read,inserted,updated,deleted} counters. */ +void dict_add_system_prefix(const char *pfx); #endif diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 060d452a2e9b..429d0871d901 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -310,6 +310,10 @@ static ulong innodb_flush_method; stopword table to be used */ static char *innobase_server_stopword_table = nullptr; +/* A comma-separated list of prefixes that designate system (not user) tables +for metrics accounting. See also dict_mem_table_is_system. */ +static char *extra_system_table_prefixes = nullptr; + /* Below we have boolean-valued start-up parameters, and their default values */ @@ -5446,6 +5450,15 @@ static int innobase_init_files(dict_init_mode_t dict_init_mode, /* Turn on monitor counters that are default on */ srv_mon_default_on(); + if (extra_system_table_prefixes) { + char *copy = strdup(extra_system_table_prefixes); + char *saveptr, *tok; + for (tok=my_strtok_r(copy, ",", &saveptr); tok; tok=my_strtok_r(NULL, ",", &saveptr)) { + dict_add_system_prefix(tok); + } + free(copy); + } + /* Unit Tests */ #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR unit_test_os_file_get_parent_dir(); @@ -21797,6 +21810,12 @@ static MYSQL_SYSVAR_STR(ft_server_stopword_table, "The user supplied stopword table name.", innodb_stopword_table_validate, nullptr, nullptr); +static MYSQL_SYSVAR_STR(extra_system_table_prefixes, + extra_system_table_prefixes, + PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_RQCMDARG, + "Additional prefixes that designate system (not user) tables for metrics accounting.", + nullptr, nullptr, nullptr); + extern uint srv_flush_log_at_timeout; static MYSQL_SYSVAR_UINT(flush_log_at_timeout, srv_flush_log_at_timeout, PLUGIN_VAR_OPCMDARG, @@ -23006,6 +23025,7 @@ static SYS_VAR *innobase_system_variables[] = { MYSQL_SYSVAR(ft_aux_table), MYSQL_SYSVAR(ft_enable_diag_print), MYSQL_SYSVAR(ft_server_stopword_table), + MYSQL_SYSVAR(extra_system_table_prefixes), MYSQL_SYSVAR(ft_user_stopword_table), MYSQL_SYSVAR(disable_sort_file_cache), MYSQL_SYSVAR(stats_on_metadata),