diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-11-13 21:54:21 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-11-13 21:54:21 +0200 |
commit | d7a582489900ea175d9659304c4fdc39b3880014 (patch) | |
tree | 06a2485b15b84fedf197c573276441ea8d8bccb0 /sql/sql_admin.cc | |
parent | 97569d3c37a66bc941b933ac7c2cefa5430a5175 (diff) | |
parent | b2029c0300bf8c311ff5d9fdc4b73a9e48bf6930 (diff) | |
download | mariadb-git-d7a582489900ea175d9659304c4fdc39b3880014.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql/sql_admin.cc')
-rw-r--r-- | sql/sql_admin.cc | 108 |
1 files changed, 81 insertions, 27 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index dc9b971f2ed..2d6f891f56f 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2019, MariaDB + Copyright (c) 2011, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,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) @@ -90,10 +90,10 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) { - int error= 0; + int error= 0, create_error= 0; TABLE tmp_table, *table; TABLE_LIST *pos_in_locked_tables= 0; - TABLE_SHARE *share; + TABLE_SHARE *share= 0; bool has_mdl_lock= FALSE; char from[FN_REFLEN],tmp[FN_REFLEN+32]; const char **ext; @@ -206,6 +206,17 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, HA_EXTRA_NOT_USED, NULL); table_list->table= 0; } + else + { + /* + Table open failed, maybe because we run out of memory. + Close all open tables and relaese all MDL locks + */ + tdc_release_share(share); + share->tdc->flush(thd, true); + share= 0; + } + /* After this point we have an exclusive metadata lock on our table in both cases when table was successfully open in mysql_admin_table() @@ -219,11 +230,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, goto end; } if (dd_recreate_table(thd, table_list->db.str, table_list->table_name.str)) - { - error= send_check_errmsg(thd, table_list, "repair", - "Failed generating table from .frm file"); - goto end; - } + create_error= send_check_errmsg(thd, table_list, "repair", + "Failed generating table from .frm file"); /* 'FALSE' for 'using_transactions' means don't postpone invalidation till the end of a transaction, but do it @@ -236,6 +244,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, "Failed restoring .MYD file"); goto end; } + if (create_error) + goto end; if (thd->locked_tables_list.locked_tables()) { @@ -263,7 +273,8 @@ end: if (table == &tmp_table) { closefrm(table); - tdc_release_share(table->s); + if (share) + tdc_release_share(share); } /* In case of a temporary table there will be no metadata lock. */ if (unlikely(error) && has_mdl_lock) @@ -418,6 +429,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 @@ -486,6 +541,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) { @@ -592,6 +654,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, #endif DBUG_PRINT("admin", ("table: %p", table->table)); + if (table->schema_table) + { + result_code= HA_ADMIN_NOT_IMPLEMENTED; + goto send_result; + } + if (prepare_func) { DBUG_PRINT("admin", ("calling prepare_func")); @@ -650,12 +718,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, goto send_result; } - if (table->schema_table) - { - result_code= HA_ADMIN_NOT_IMPLEMENTED; - goto send_result; - } - if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { /* purecov: begin inspected */ @@ -1338,10 +1400,10 @@ bool Sql_cmd_analyze_table::execute(THD *thd) m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; -error: #ifdef WITH_WSREP -wsrep_error_label: -#endif + wsrep_error_label: +#endif /* WITH_WSREP */ +error: DBUG_RETURN(res); } @@ -1380,7 +1442,6 @@ bool Sql_cmd_optimize_table::execute(THD *thd) 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) : @@ -1399,9 +1460,6 @@ bool Sql_cmd_optimize_table::execute(THD *thd) m_lex->query_tables= first_table; error: -#ifdef WITH_WSREP -wsrep_error_label: -#endif DBUG_RETURN(res); } @@ -1416,7 +1474,6 @@ bool Sql_cmd_repair_table::execute(THD *thd) 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), @@ -1435,8 +1492,5 @@ bool Sql_cmd_repair_table::execute(THD *thd) m_lex->query_tables= first_table; error: -#ifdef WITH_WSREP -wsrep_error_label: -#endif DBUG_RETURN(res); } |