Commit ab513b00 authored by Monty's avatar Monty Committed by Sergei Golubchik

Optimize checking if a table is a statistics table

parent a00e99ac
...@@ -153,7 +153,8 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) ...@@ -153,7 +153,8 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
if (t->reginfo.lock_type >= TL_FIRST_WRITE) if (t->reginfo.lock_type >= TL_FIRST_WRITE)
{ {
if (t->s->table_category == TABLE_CATEGORY_SYSTEM) if (t->s->table_category == TABLE_CATEGORY_SYSTEM ||
t->s->table_category == TABLE_CATEGORY_STATISTICS)
system_count++; system_count++;
if (t->db_stat & HA_READ_ONLY) if (t->db_stat & HA_READ_ONLY)
......
...@@ -9616,9 +9616,11 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list) ...@@ -9616,9 +9616,11 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list)
for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global) for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global)
{ {
DBUG_ASSERT(tables->table->s->table_category == TABLE_CATEGORY_SYSTEM); TABLE *table= tables->table;
tables->table->file->row_logging= 0; DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM ||
tables->table->use_all_columns(); table->s->table_category == TABLE_CATEGORY_STATISTICS);
table->file->row_logging= 0;
table->use_all_columns();
} }
lex->restore_backup_query_tables_list(&query_tables_list_backup); lex->restore_backup_query_tables_list(&query_tables_list_backup);
......
...@@ -3300,7 +3300,7 @@ read_statistics_for_tables(THD *thd, TABLE_LIST *tables, bool force_reload) ...@@ -3300,7 +3300,7 @@ read_statistics_for_tables(THD *thd, TABLE_LIST *tables, bool force_reload)
statistics_for_tables_is_needed= true; statistics_for_tables_is_needed= true;
} }
} }
else if (is_stat_table(tl->db, tl->alias)) else if (table_share->table_category == TABLE_CATEGORY_STATISTICS)
found_stat_table= true; found_stat_table= true;
} }
......
...@@ -134,7 +134,9 @@ static bool fix_type_pointers(const char ***typelib_value_names, ...@@ -134,7 +134,9 @@ static bool fix_type_pointers(const char ***typelib_value_names,
static field_index_t find_field(Field **fields, uchar *record, uint start, static field_index_t find_field(Field **fields, uchar *record, uint start,
uint length); uint length);
inline bool is_system_table_name(const char *name, size_t length); static inline bool is_system_table_name(const char *name, size_t length);
static inline bool is_statistics_table_name(const char *name, size_t length);
/************************************************************************** /**************************************************************************
Object_creation_ctx implementation. Object_creation_ctx implementation.
...@@ -315,13 +317,12 @@ TABLE_CATEGORY get_table_category(const Lex_ident_db &db, ...@@ -315,13 +317,12 @@ TABLE_CATEGORY get_table_category(const Lex_ident_db &db,
if (is_system_table_name(name.str, name.length)) if (is_system_table_name(name.str, name.length))
return TABLE_CATEGORY_SYSTEM; return TABLE_CATEGORY_SYSTEM;
if (name.streq(GENERAL_LOG_NAME)) if (is_statistics_table_name(name.str, name.length))
return TABLE_CATEGORY_LOG; return TABLE_CATEGORY_STATISTICS;
if (name.streq(SLOW_LOG_NAME))
return TABLE_CATEGORY_LOG;
if (name.streq(TRANSACTION_REG_NAME)) if (name.streq(GENERAL_LOG_NAME) ||
name.streq(SLOW_LOG_NAME) ||
name.streq(TRANSACTION_REG_NAME))
return TABLE_CATEGORY_LOG; return TABLE_CATEGORY_LOG;
} }
...@@ -578,7 +579,7 @@ void free_table_share(TABLE_SHARE *share) ...@@ -578,7 +579,7 @@ void free_table_share(TABLE_SHARE *share)
and should not contain user tables. and should not contain user tables.
*/ */
inline bool is_system_table_name(const char *name, size_t length) static inline bool is_system_table_name(const char *name, size_t length)
{ {
CHARSET_INFO *ci= system_charset_info; CHARSET_INFO *ci= system_charset_info;
...@@ -604,17 +605,6 @@ inline bool is_system_table_name(const char *name, size_t length) ...@@ -604,17 +605,6 @@ inline bool is_system_table_name(const char *name, size_t length)
my_tolower(ci, name[2]) == 'm' && my_tolower(ci, name[2]) == 'm' &&
my_tolower(ci, name[3]) == 'e') || my_tolower(ci, name[3]) == 'e') ||
/* one of mysql.*_stat tables, but not mysql.innodb* tables*/
((my_tolower(ci, name[length-5]) == 's' &&
my_tolower(ci, name[length-4]) == 't' &&
my_tolower(ci, name[length-3]) == 'a' &&
my_tolower(ci, name[length-2]) == 't' &&
my_tolower(ci, name[length-1]) == 's') &&
!(my_tolower(ci, name[0]) == 'i' &&
my_tolower(ci, name[1]) == 'n' &&
my_tolower(ci, name[2]) == 'n' &&
my_tolower(ci, name[3]) == 'o')) ||
/* mysql.event table */ /* mysql.event table */
(my_tolower(ci, name[0]) == 'e' && (my_tolower(ci, name[0]) == 'e' &&
my_tolower(ci, name[1]) == 'v' && my_tolower(ci, name[1]) == 'v' &&
...@@ -627,6 +617,29 @@ inline bool is_system_table_name(const char *name, size_t length) ...@@ -627,6 +617,29 @@ inline bool is_system_table_name(const char *name, size_t length)
} }
static inline bool
is_statistics_table_name(const char *name, size_t length)
{
CHARSET_INFO *ci= system_charset_info;
if (length > 6)
{
/* one of mysql.*_stat tables, but not mysql.innodb* tables*/
if ((my_tolower(ci, name[length-5]) == 's' &&
my_tolower(ci, name[length-4]) == 't' &&
my_tolower(ci, name[length-3]) == 'a' &&
my_tolower(ci, name[length-2]) == 't' &&
my_tolower(ci, name[length-1]) == 's') &&
!(my_tolower(ci, name[0]) == 'i' &&
my_tolower(ci, name[1]) == 'n' &&
my_tolower(ci, name[2]) == 'n' &&
my_tolower(ci, name[3]) == 'o'))
return 1;
}
return 0;
}
/* /*
Read table definition from a binary / text based .frm file Read table definition from a binary / text based .frm file
......
...@@ -463,6 +463,11 @@ enum enum_table_category ...@@ -463,6 +463,11 @@ enum enum_table_category
*/ */
TABLE_CATEGORY_SYSTEM=3, TABLE_CATEGORY_SYSTEM=3,
/**
Persistent statistics table
*/
TABLE_CATEGORY_STATISTICS= 4,
/** /**
Log tables. Log tables.
These tables are an interface provided by the system These tables are an interface provided by the system
...@@ -483,7 +488,7 @@ enum enum_table_category ...@@ -483,7 +488,7 @@ enum enum_table_category
The server implementation perform writes. The server implementation perform writes.
Log tables are cached in the table cache. Log tables are cached in the table cache.
*/ */
TABLE_CATEGORY_LOG=4, TABLE_CATEGORY_LOG=5,
/* /*
Types below are read only tables, not affected by FLUSH TABLES or Types below are read only tables, not affected by FLUSH TABLES or
...@@ -509,7 +514,7 @@ enum enum_table_category ...@@ -509,7 +514,7 @@ enum enum_table_category
to I_S tables in the table cache, which should use to I_S tables in the table cache, which should use
this table type. this table type.
*/ */
TABLE_CATEGORY_INFORMATION=5, TABLE_CATEGORY_INFORMATION=6,
/** /**
Performance schema tables. Performance schema tables.
...@@ -531,7 +536,7 @@ enum enum_table_category ...@@ -531,7 +536,7 @@ enum enum_table_category
The server implementation perform writes. The server implementation perform writes.
Performance tables are cached in the table cache. Performance tables are cached in the table cache.
*/ */
TABLE_CATEGORY_PERFORMANCE=6 TABLE_CATEGORY_PERFORMANCE=7
}; };
typedef enum enum_table_category TABLE_CATEGORY; typedef enum enum_table_category TABLE_CATEGORY;
......
...@@ -1444,15 +1444,21 @@ bool wsrep_check_mode_after_open_table (THD *thd, ...@@ -1444,15 +1444,21 @@ bool wsrep_check_mode_after_open_table (THD *thd,
(db_type == DB_TYPE_ARIA && wsrep_check_mode(WSREP_MODE_REPLICATE_ARIA))); (db_type == DB_TYPE_ARIA && wsrep_check_mode(WSREP_MODE_REPLICATE_ARIA)));
TABLE *tbl= tables->table; TABLE *tbl= tables->table;
DBUG_ASSERT(tbl);
if (replicate) if (replicate)
{ {
/* It is not recommended to replicate MyISAM as it lacks rollback feature /*
but if user demands then actions are replicated using TOI. It is not recommended to replicate MyISAM as it lacks rollback
Following code will kick-start the TOI but this has to be done only once feature but if user demands then actions are replicated using TOI.
per statement. Following code will kick-start the TOI but this has to be done
Note: kick-start will take-care of creating isolation key for all tables only once per statement.
involved in the list (provided all of them are MYISAM or Aria tables). */
if (!is_stat_table(tables->db, tables->alias)) Note: kick-start will take-care of creating isolation key for
all tables involved in the list (provided all of them are MYISAM
or Aria tables).
*/
if ((tbl && tbl->s->table_category != TABLE_CATEGORY_STATISTICS) ||
(!tbl && !is_stat_table(tables->db, tables->alias)))
{ {
if (tbl->s->primary_key == MAX_KEY && if (tbl->s->primary_key == MAX_KEY &&
wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY)) wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY))
...@@ -1470,13 +1476,14 @@ bool wsrep_check_mode_after_open_table (THD *thd, ...@@ -1470,13 +1476,14 @@ bool wsrep_check_mode_after_open_table (THD *thd,
db_type != DB_TYPE_PERFORMANCE_SCHEMA) db_type != DB_TYPE_PERFORMANCE_SCHEMA)
{ {
bool is_system_db= (tbl && bool is_system_db= (tbl &&
((strcmp(tbl->s->db.str, "mysql") == 0) || (!strcmp(tbl->s->db.str, "mysql") ||
(strcmp(tbl->s->db.str, "information_schema") == 0))); (tbl->s->table_category ==
TABLE_CATEGORY_INFORMATION &&
!strcmp(tbl->s->db.str, "information_schema"))));
if (!is_system_db && if (!is_system_db &&
!is_temporary_table(tables)) !is_temporary_table(tables))
{ {
if (db_type != DB_TYPE_INNODB && if (db_type != DB_TYPE_INNODB &&
wsrep_check_mode(WSREP_MODE_STRICT_REPLICATION)) wsrep_check_mode(WSREP_MODE_STRICT_REPLICATION))
{ {
......
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