summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2018-06-14 15:47:39 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2018-06-15 09:04:26 +0300
commitc69357d8d4592b746a2dd7074c8fb6a437098b2a (patch)
tree8bbcb53dd48cca7fda5c496094bf56bb71842262 /storage
parentf4387288ab54837aa84ce728b2ce61e52850e4ec (diff)
downloadmariadb-git-c69357d8d4592b746a2dd7074c8fb6a437098b2a.tar.gz
MDEV-15611 Due to the failure of foreign key detection, Galera slave node killed himself.
Merge following change from 10.2 revision-id: d52cff9f10aeea208a1058f7b5527e602125584c (mariadb-10.2.14-25-gd52cff9) parent(s): bc2501453c3ab9a2cf3516bc3557de8665bc2776 author: Sachin Setiya committer: Sachin Setiya timestamp: 2018-04-04 12:26:06 +0530 message: MDEV-15611 Due to the failure of foreign key detection, Galera... slave node killed himself. Problem:- If we try to delete table with foreign key and table whom it is referring with wsrep_slave_threads>1 then galera tries to execute both Delete_rows_log-event in parallel, which should not happen. Solution:- This is happening because we do not have foreign key info in write set. Upto version 10.2.7 it used to work fine. Actually it happening because of issue in commit 2f342c4. wsrep_must_process_fk should be used with negation.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/row/row0upd.cc141
-rw-r--r--storage/xtradb/row/row0upd.cc141
2 files changed, 150 insertions, 132 deletions
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index e2de47bf86a..33f46882651 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1803,6 +1803,23 @@ row_upd_store_row(
}
}
+#ifdef WITH_WSREP
+/** Determine if a FOREIGN KEY constraint needs to be processed.
+@param[in] node query node
+@param[in] trx transaction
+@return whether the node cannot be ignored */
+
+inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
+{
+ if (!wsrep_on_trx(trx)) {
+ return false;
+ }
+ return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
+ || static_cast<upd_node_t*>(node->common.parent)->cascade_node
+ != node;
+}
+#endif /* WITH_WSREP */
+
/***********************************************************//**
Updates a secondary index entry of a row.
@return DB_SUCCESS if operation successfully completed, else error
@@ -1833,7 +1850,7 @@ row_upd_sec_index_entry(
referenced = row_upd_index_is_referenced(index, trx);
#ifdef WITH_WSREP
- ibool foreign = wsrep_row_upd_index_is_foreign(index, trx);
+ bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
#endif /* WITH_WSREP */
heap = mem_heap_create(1024);
@@ -1962,61 +1979,61 @@ row_upd_sec_index_entry(
row_ins_sec_index_entry() below */
if (!rec_get_deleted_flag(
rec, dict_table_is_comp(index->table))) {
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
err = btr_cur_del_mark_set_sec_rec(
0, btr_cur, TRUE, thr, &mtr);
- if (err == DB_SUCCESS && referenced) {
-
- ulint* offsets;
-
- offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
- &heap);
-
- /* NOTE that the following call loses
- the position of pcur ! */
- err = row_upd_check_references_constraints(
- node, &pcur, index->table,
- index, offsets, thr, &mtr);
+ if (err != DB_SUCCESS) {
+ break;
}
+
#ifdef WITH_WSREP
- if (err == DB_SUCCESS && !referenced &&
- wsrep_on_trx(trx) &&
- !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !(parent && que_node_get_type(parent) ==
- QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
- ulint* offsets =
- rec_get_offsets(
+ if (!referenced && foreign
+ && wsrep_must_process_fk(node, trx)
+ && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ ulint* offsets = rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
+
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: sec index FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
}
#endif /* WITH_WSREP */
}
- break;
+
+ if (referenced) {
+
+ ulint* offsets;
+
+ offsets = rec_get_offsets(
+ rec, index, NULL, ULINT_UNDEFINED,
+ &heap);
+
+ /* NOTE that the following call loses
+ the position of pcur ! */
+ err = row_upd_check_references_constraints(
+ node, &pcur, index->table,
+ index, offsets, thr, &mtr);
+ }
}
btr_pcur_close(&pcur);
@@ -2185,9 +2202,6 @@ row_upd_clust_rec_by_insert(
rec_t* rec;
ulint* offsets = NULL;
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
ut_ad(node);
ut_ad(dict_index_is_clust(index));
@@ -2269,35 +2283,31 @@ err_exit:
if (err != DB_SUCCESS) {
goto err_exit;
}
- }
#ifdef WITH_WSREP
- if (!referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if ((foreign && wsrep_must_process_fk(node, trx))) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: insert FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- if (err != DB_SUCCESS) {
- goto err_exit;
- }
- }
#endif /* WITH_WSREP */
+ }
}
mtr_commit(mtr);
@@ -2500,7 +2510,7 @@ row_upd_del_mark_clust_rec(
dberr_t err;
#ifdef WITH_WSREP
rec_t* rec;
- que_node_t *parent = que_node_get_parent(node);
+ trx_t* trx = thr_get_trx(thr) ;
#endif /* WITH_WSREP */
ut_ad(node);
@@ -2529,38 +2539,37 @@ row_upd_del_mark_clust_rec(
btr_cur_get_block(btr_cur), btr_cur_get_rec(btr_cur),
#endif /* WITH_WSREP */
index, offsets, thr, mtr);
- if (err == DB_SUCCESS && referenced) {
+ if (err != DB_SUCCESS) {
+ } else if (referenced) {
/* NOTE that the following call loses the position of pcur ! */
err = row_upd_check_references_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
- }
#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr) ;
- if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: clust rec FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: clust rec referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- }
#endif /* WITH_WSREP */
+ }
mtr_commit(mtr);
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 9ac72f8d068..93ccc07c9af 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -1806,6 +1806,23 @@ row_upd_store_row(
}
}
+#ifdef WITH_WSREP
+/** Determine if a FOREIGN KEY constraint needs to be processed.
+@param[in] node query node
+@param[in] trx transaction
+@return whether the node cannot be ignored */
+
+inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
+{
+ if (!wsrep_on_trx(trx)) {
+ return false;
+ }
+ return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
+ || static_cast<upd_node_t*>(node->common.parent)->cascade_node
+ != node;
+}
+#endif /* WITH_WSREP */
+
/***********************************************************//**
Updates a secondary index entry of a row.
@return DB_SUCCESS if operation successfully completed, else error
@@ -1836,7 +1853,7 @@ row_upd_sec_index_entry(
referenced = row_upd_index_is_referenced(index, trx);
#ifdef WITH_WSREP
- ibool foreign = wsrep_row_upd_index_is_foreign(index, trx);
+ bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
#endif /* WITH_WSREP */
heap = mem_heap_create(1024);
@@ -1968,61 +1985,61 @@ row_upd_sec_index_entry(
row_ins_sec_index_entry() below */
if (!rec_get_deleted_flag(
rec, dict_table_is_comp(index->table))) {
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
err = btr_cur_del_mark_set_sec_rec(
0, btr_cur, TRUE, thr, &mtr);
- if (err == DB_SUCCESS && referenced) {
-
- ulint* offsets;
-
- offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
- &heap);
-
- /* NOTE that the following call loses
- the position of pcur ! */
- err = row_upd_check_references_constraints(
- node, &pcur, index->table,
- index, offsets, thr, &mtr);
+ if (err != DB_SUCCESS) {
+ break;
}
+
#ifdef WITH_WSREP
- if (err == DB_SUCCESS && !referenced &&
- wsrep_on_trx(trx) &&
- !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !(parent && que_node_get_type(parent) ==
- QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
- ulint* offsets =
- rec_get_offsets(
+ if (!referenced && foreign
+ && wsrep_must_process_fk(node, trx)
+ && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ ulint* offsets = rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
+
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: sec index FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
}
#endif /* WITH_WSREP */
}
- break;
+
+ if (referenced) {
+
+ ulint* offsets;
+
+ offsets = rec_get_offsets(
+ rec, index, NULL, ULINT_UNDEFINED,
+ &heap);
+
+ /* NOTE that the following call loses
+ the position of pcur ! */
+ err = row_upd_check_references_constraints(
+ node, &pcur, index->table,
+ index, offsets, thr, &mtr);
+ }
}
btr_pcur_close(&pcur);
@@ -2191,9 +2208,6 @@ row_upd_clust_rec_by_insert(
rec_t* rec;
ulint* offsets = NULL;
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
ut_ad(node);
ut_ad(dict_index_is_clust(index));
@@ -2278,35 +2292,31 @@ err_exit:
if (err != DB_SUCCESS) {
goto err_exit;
}
- }
#ifdef WITH_WSREP
- if (!referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if ((foreign && wsrep_must_process_fk(node, trx))) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: insert FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- if (err != DB_SUCCESS) {
- goto err_exit;
- }
- }
#endif /* WITH_WSREP */
+ }
}
mtr_commit(mtr);
@@ -2512,7 +2522,7 @@ row_upd_del_mark_clust_rec(
dberr_t err;
#ifdef WITH_WSREP
rec_t* rec;
- que_node_t *parent = que_node_get_parent(node);
+ trx_t* trx = thr_get_trx(thr) ;
#endif /* WITH_WSREP */
ut_ad(node);
@@ -2541,38 +2551,37 @@ row_upd_del_mark_clust_rec(
btr_cur_get_block(btr_cur), btr_cur_get_rec(btr_cur),
#endif /* WITH_WSREP */
index, offsets, thr, mtr);
- if (err == DB_SUCCESS && referenced) {
+ if (err != DB_SUCCESS) {
+ } else if (referenced) {
/* NOTE that the following call loses the position of pcur ! */
err = row_upd_check_references_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
- }
#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr) ;
- if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: clust rec FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: clust rec referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- }
#endif /* WITH_WSREP */
+ }
mtr_commit(mtr);