diff options
Diffstat (limited to 'sql/sql_admin.cc')
-rw-r--r-- | sql/sql_admin.cc | 84 |
1 files changed, 68 insertions, 16 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index b5c8514c302..0a6e76d117f 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -32,7 +32,7 @@ #include "strfunc.h" #include "sql_admin.h" #include "sql_statistics.h" - +#include "wsrep_mysqld.h" /* Prepare, run and cleanup for mysql_recreate_table() */ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list) @@ -323,7 +323,7 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table, bool is_view_operator_func) { LEX *lex= thd->lex; - SELECT_LEX *select= &lex->select_lex; + SELECT_LEX *select= lex->first_select_lex(); TABLE_LIST *save_next_global, *save_next_local; bool open_error; save_next_global= table->next_global; @@ -436,6 +436,50 @@ dbug_err: return open_error; } +#ifdef WITH_WSREP + /* + OPTIMIZE, REPAIR and ALTER may take MDL locks not only for the affected table, but + also for the table referenced by foreign key constraint. + This wsrep_toi_replication() function handles TOI replication for OPTIMIZE and REPAIR + so that certification keys for potential FK parent tables are also appended in the + write set. + ALTER TABLE case is handled elsewhere. + */ +static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables) +{ + if (!WSREP(thd) || !WSREP_CLIENT(thd)) return false; + + LEX *lex= thd->lex; + /* only handle OPTIMIZE and REPAIR here */ + switch (lex->sql_command) + { + case SQLCOM_OPTIMIZE: + case SQLCOM_REPAIR: + break; + default: + return false; + } + + close_thread_tables(thd); + wsrep::key_array keys; + + wsrep_append_fk_parent_table(thd, tables, &keys); + + /* now TOI replication, with no locks held */ + if (keys.empty()) + { + WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, tables); + } else { + WSREP_TO_ISOLATION_BEGIN_FK_TABLES(NULL, NULL, tables, &keys) { + return true; + } + } + return false; + + wsrep_error_label: + return true; +} +#endif /* WITH_WSREP */ /* RETURN VALUES @@ -504,6 +548,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, close_thread_tables(thd); for (table= tables; table; table= table->next_local) table->table= NULL; +#ifdef WITH_WSREP + if (wsrep_toi_replication(thd, tables)) + { + WSREP_INFO("wsrep TOI replication of has failed, skipping OPTIMIZE"); + goto err; + } +#endif /* WITH_WSREP */ for (table= tables; table; table= table->next_local) { @@ -797,7 +848,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, collect_eis= (table->table->s->table_category == TABLE_CATEGORY_USER && !(lex->alter_info.flags & ALTER_PARTITION_ADMIN) && - (get_use_stat_tables_mode(thd) > NEVER || + (check_eits_collection_allowed(thd) || lex->with_persistent_for_clause)); } @@ -1324,7 +1375,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) bool Sql_cmd_analyze_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; thr_lock_type lock_type = TL_READ_NO_INSERT; DBUG_ENTER("Sql_cmd_analyze_table::execute"); @@ -1332,6 +1383,9 @@ bool Sql_cmd_analyze_table::execute(THD *thd) if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table, FALSE, UINT_MAX, FALSE)) goto error; + if (thd->has_read_only_protection()) + goto error; + WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "analyze", lock_type, 1, 0, 0, 0, @@ -1344,11 +1398,13 @@ bool Sql_cmd_analyze_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; +#ifdef WITH_WSREP + wsrep_error_label: +#endif /* WITH_WSREP */ error: -WSREP_ERROR_LABEL: DBUG_RETURN(res); } @@ -1356,7 +1412,7 @@ WSREP_ERROR_LABEL: bool Sql_cmd_check_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; thr_lock_type lock_type = TL_READ_NO_INSERT; bool res= TRUE; DBUG_ENTER("Sql_cmd_check_table::execute"); @@ -1369,7 +1425,7 @@ bool Sql_cmd_check_table::execute(THD *thd) lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0, &handler::ha_check, &view_check); - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: @@ -1380,14 +1436,13 @@ error: bool Sql_cmd_optimize_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; DBUG_ENTER("Sql_cmd_optimize_table::execute"); if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table, FALSE, UINT_MAX, FALSE)) goto error; /* purecov: inspected */ - WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); res= (specialflag & SPECIAL_NO_NEW_FUNC) ? mysql_recreate_table(thd, first_table, true) : @@ -1402,11 +1457,10 @@ bool Sql_cmd_optimize_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: -WSREP_ERROR_LABEL: DBUG_RETURN(res); } @@ -1414,14 +1468,13 @@ WSREP_ERROR_LABEL: bool Sql_cmd_repair_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; DBUG_ENTER("Sql_cmd_repair_table::execute"); if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table, FALSE, UINT_MAX, FALSE)) goto error; /* purecov: inspected */ - WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "repair", TL_WRITE, 1, MY_TEST(m_lex->check_opt.sql_flags & TT_USEFRM), @@ -1436,10 +1489,9 @@ bool Sql_cmd_repair_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: -WSREP_ERROR_LABEL: DBUG_RETURN(res); } |