diff --git a/sql/lock.cc b/sql/lock.cc index a9c866a7641..936802f6340 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -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->s->table_category == TABLE_CATEGORY_SYSTEM) + if (t->s->table_category == TABLE_CATEGORY_SYSTEM || + t->s->table_category == TABLE_CATEGORY_STATISTICS) system_count++; if (t->db_stat & HA_READ_ONLY) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2ffd666a6e4..921687dce63 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -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) { - DBUG_ASSERT(tables->table->s->table_category == TABLE_CATEGORY_SYSTEM); - tables->table->file->row_logging= 0; - tables->table->use_all_columns(); + TABLE *table= tables->table; + DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM || + 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); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index f1e7358b346..05c50ff0bda 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3300,7 +3300,7 @@ read_statistics_for_tables(THD *thd, TABLE_LIST *tables, bool force_reload) 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; } diff --git a/sql/table.cc b/sql/table.cc index 24c27597458..181fc32fdbb 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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, 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. @@ -315,13 +317,12 @@ TABLE_CATEGORY get_table_category(const Lex_ident_db &db, if (is_system_table_name(name.str, name.length)) return TABLE_CATEGORY_SYSTEM; - if (name.streq(GENERAL_LOG_NAME)) - return TABLE_CATEGORY_LOG; + if (is_statistics_table_name(name.str, name.length)) + 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; } @@ -578,7 +579,7 @@ void free_table_share(TABLE_SHARE *share) 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; @@ -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[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 */ (my_tolower(ci, name[0]) == 'e' && my_tolower(ci, name[1]) == 'v' && @@ -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 diff --git a/sql/table.h b/sql/table.h index 96f9747a2c3..314fcccbdcd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -463,6 +463,11 @@ enum enum_table_category */ TABLE_CATEGORY_SYSTEM=3, + /** + Persistent statistics table + */ + TABLE_CATEGORY_STATISTICS= 4, + /** Log tables. These tables are an interface provided by the system @@ -483,7 +488,7 @@ enum enum_table_category The server implementation perform writes. 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 @@ -509,7 +514,7 @@ enum enum_table_category to I_S tables in the table cache, which should use this table type. */ - TABLE_CATEGORY_INFORMATION=5, + TABLE_CATEGORY_INFORMATION=6, /** Performance schema tables. @@ -531,7 +536,7 @@ enum enum_table_category The server implementation perform writes. Performance tables are cached in the table cache. */ - TABLE_CATEGORY_PERFORMANCE=6 + TABLE_CATEGORY_PERFORMANCE=7 }; typedef enum enum_table_category TABLE_CATEGORY; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index ff2130539bc..bc6f8283a5d 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -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))); TABLE *tbl= tables->table; + DBUG_ASSERT(tbl); if (replicate) { - /* It is not recommended to replicate MyISAM as it lacks rollback feature - but if user demands then actions are replicated using TOI. - Following code will kick-start the TOI but this has to be done only once - per statement. - 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 (!is_stat_table(tables->db, tables->alias)) + /* + It is not recommended to replicate MyISAM as it lacks rollback + feature but if user demands then actions are replicated using TOI. + Following code will kick-start the TOI but this has to be done + only once per statement. + + 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 && wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY)) @@ -1470,13 +1476,14 @@ bool wsrep_check_mode_after_open_table (THD *thd, db_type != DB_TYPE_PERFORMANCE_SCHEMA) { bool is_system_db= (tbl && - ((strcmp(tbl->s->db.str, "mysql") == 0) || - (strcmp(tbl->s->db.str, "information_schema") == 0))); + (!strcmp(tbl->s->db.str, "mysql") || + (tbl->s->table_category == + TABLE_CATEGORY_INFORMATION && + !strcmp(tbl->s->db.str, "information_schema")))); if (!is_system_db && !is_temporary_table(tables)) { - if (db_type != DB_TYPE_INNODB && wsrep_check_mode(WSREP_MODE_STRICT_REPLICATION)) {