summaryrefslogtreecommitdiff
path: root/sql/sql_alter.cc
diff options
context:
space:
mode:
authorDaniele Sciascia <daniele.sciascia@galeracluster.com>2018-05-22 16:45:27 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2018-08-02 09:03:27 +0300
commit4d2b5523695ea6b6f7e6cde406165a09d517dfeb (patch)
tree1070fb8fa71cf1ed1dae6c0d6c1a4e673435ecfe /sql/sql_alter.cc
parentb286a9f8238c4b441d3e42d2b56ba3d5f563bfb1 (diff)
downloadmariadb-git-4d2b5523695ea6b6f7e6cde406165a09d517dfeb.tar.gz
Fix FK constraint violation in applier, after ALTER TABLE ADD FK
Adding a FK constraint to an existing table (ALTER TABLE ADD FOREIGN KEY) causes the applier to fail, if a concurrent DML statement that violate the new constraint (i.e. a DELETE or UPDATE of record in the parent table). For exmaple, the following scenario causes a crash in the applier: 1. ALTER successfully adds FK constraint in node_1 2. On node_2 is UPDATE is in pre_commit() and has certified successfully 3. ALTER is delivered in node_2 and BF aborts DML 4. Applying UPDATE event causes FK violation in node_1 To avoid this situation it is necessary for UPDATE to fail during certification. And for the UPDATE to fail certfication it is necessary that ALTER appends certification keys for both the child and the parent table. Before this patch, ALTER TABLE ADD FK only appended keys for child table which is ALTERed.
Diffstat (limited to 'sql/sql_alter.cc')
-rw-r--r--sql/sql_alter.cc17
1 files changed, 9 insertions, 8 deletions
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 0b4636c1f0f..1d69b06d798 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -106,14 +106,10 @@ bool Alter_table_statement::execute(THD *thd)
(!thd->is_current_stmt_binlog_format_row() ||
!find_temporary_table(thd, first_table)))
{
- if (wsrep_to_isolation_begin(thd,
- lex->name.str ? select_lex->db : NULL,
- lex->name.str ? lex->name.str : NULL,
- first_table))
- {
- WSREP_WARN("ALTER TABLE isolation failure");
- DBUG_RETURN(TRUE);
- }
+ WSREP_TO_ISOLATION_BEGIN_ALTER(((lex->name.str) ? select_lex->db : NULL),
+ ((lex->name.str) ? lex->name.str : NULL),
+ first_table,
+ &alter_info);
thd->variables.auto_increment_offset = 1;
thd->variables.auto_increment_increment = 1;
@@ -128,6 +124,11 @@ bool Alter_table_statement::execute(THD *thd)
lex->ignore, lex->online);
#ifdef WITH_WSREP
+error:
+ {
+ WSREP_WARN("ALTER TABLE isolation failure");
+ DBUG_RETURN(TRUE);
+ }
#endif /* WITH_WSREP */
DBUG_RETURN(result);
}