summaryrefslogtreecommitdiff
path: root/sql/sql_admin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_admin.cc')
-rw-r--r--sql/sql_admin.cc84
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);
}