summaryrefslogtreecommitdiff
path: root/sql/sql_admin.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-05-18 08:59:12 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-05-18 08:59:12 +0300
commit4240704abc2d51a2e46fb85049b601fce5d5b24c (patch)
tree7a5d40078f39746c649f27fa11ae75d44b509dec /sql/sql_admin.cc
parente861e057ad1b53e38887df66ac816626793c48cd (diff)
parentca3f497564f93d2d70d024d996bcd1136bddc5ab (diff)
downloadmariadb-git-4240704abc2d51a2e46fb85049b601fce5d5b24c.tar.gz
Merge 10.3 into 10.4
Diffstat (limited to 'sql/sql_admin.cc')
-rw-r--r--sql/sql_admin.cc77
1 files changed, 36 insertions, 41 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index a96eb58809b..273955b7541 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, 2020, MariaDB
+ Copyright (c) 2011, 2021, 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
@@ -497,7 +497,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
int (handler::*operator_func)(THD *,
HA_CHECK_OPT *),
int (view_operator_func)(THD *, TABLE_LIST*,
- HA_CHECK_OPT *))
+ HA_CHECK_OPT *),
+ bool is_cmd_replicated)
{
TABLE_LIST *table;
List<Item> field_list;
@@ -508,6 +509,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
int compl_result_code;
bool need_repair_or_alter= 0;
wait_for_commit* suspended_wfc;
+ bool is_table_modified= false;
+
DBUG_ENTER("mysql_admin_table");
DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options));
@@ -567,6 +570,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
bool open_for_modify= org_open_for_modify;
DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
+ DEBUG_SYNC(thd, "admin_command_kill_before_modify");
+
+ if (thd->is_killed())
+ break;
strxmov(table_name, db, ".", table->table_name.str, NullS);
thd->open_options|= extra_open_options;
table->lock_type= lock_type;
@@ -1219,6 +1226,13 @@ send_result_message:
break;
}
}
+ /*
+ Admin commands acquire table locks and these locks are not detected by
+ parallel replication deadlock detection-and-handling mechanism. Hence
+ they must be marked as DDL so that they are not scheduled in parallel
+ with conflicting DMLs resulting in deadlock.
+ */
+ thd->transaction.stmt.mark_executed_table_admin_cmd();
if (table->table && !table->view)
{
if (table->table->s->tmp_table)
@@ -1254,10 +1268,9 @@ send_result_message:
}
else
{
- if (trans_commit_stmt(thd) ||
- (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) &&
- trans_commit_implicit(thd)))
+ if (trans_commit_stmt(thd))
goto err;
+ is_table_modified= true;
}
close_thread_tables(thd);
thd->release_transactional_locks();
@@ -1280,6 +1293,16 @@ send_result_message:
if (protocol->write())
goto err;
+ DEBUG_SYNC(thd, "admin_command_kill_after_modify");
+ }
+ if (is_table_modified && is_cmd_replicated &&
+ (!opt_readonly || thd->slave_thread) && !thd->lex->no_write_to_binlog)
+ {
+ thd->get_stmt_da()->set_overwrite_status(true);
+ auto res= write_bin_log(thd, true, thd->query(), thd->query_length());
+ thd->get_stmt_da()->set_overwrite_status(false);
+ if (res)
+ goto err;
}
my_eof(thd);
@@ -1342,7 +1365,7 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
check_opt.key_cache= key_cache;
DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
"assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
- 0, 0, &handler::assign_to_keycache, 0));
+ 0, 0, &handler::assign_to_keycache, 0, false));
}
@@ -1369,7 +1392,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
*/
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
"preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
- &handler::preload_keys, 0));
+ &handler::preload_keys, 0, false));
}
@@ -1390,17 +1413,8 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
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,
- &handler::ha_analyze, 0);
- /* ! we write after unlocking the table */
- if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
- {
- /*
- Presumably, ANALYZE and binlog writing doesn't require synchronization
- */
- thd->get_stmt_da()->set_overwrite_status(true);
- res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- thd->get_stmt_da()->set_overwrite_status(false);
- }
+ &handler::ha_analyze, 0, true);
+
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
@@ -1426,7 +1440,7 @@ bool Sql_cmd_check_table::execute(THD *thd)
res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "check",
lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0,
- &handler::ha_check, &view_check);
+ &handler::ha_check, &view_check, false);
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
@@ -1451,17 +1465,8 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
mysql_recreate_table(thd, first_table, true) :
mysql_admin_table(thd, first_table, &m_lex->check_opt,
"optimize", TL_WRITE, 1, 0, 0, 0,
- &handler::ha_optimize, 0);
- /* ! we write after unlocking the table */
- if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
- {
- /*
- Presumably, OPTIMIZE and binlog writing doesn't require synchronization
- */
- thd->get_stmt_da()->set_overwrite_status(true);
- res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- thd->get_stmt_da()->set_overwrite_status(false);
- }
+ &handler::ha_optimize, 0, true);
+
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
@@ -1484,18 +1489,8 @@ bool Sql_cmd_repair_table::execute(THD *thd)
TL_WRITE, 1,
MY_TEST(m_lex->check_opt.sql_flags & TT_USEFRM),
HA_OPEN_FOR_REPAIR, &prepare_for_repair,
- &handler::ha_repair, &view_repair);
+ &handler::ha_repair, &view_repair, true);
- /* ! we write after unlocking the table */
- if (!res && !m_lex->no_write_to_binlog && (!opt_readonly || thd->slave_thread))
- {
- /*
- Presumably, REPAIR and binlog writing doesn't require synchronization
- */
- thd->get_stmt_da()->set_overwrite_status(true);
- res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- thd->get_stmt_da()->set_overwrite_status(false);
- }
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;