summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/galera/r/galera_fk_cascade_delete.result18
-rw-r--r--mysql-test/suite/galera/r/galera_fk_cascade_delete_debug.result69
-rw-r--r--mysql-test/suite/galera/t/galera_fk_cascade_delete.test18
-rw-r--r--mysql-test/suite/galera/t/galera_fk_cascade_delete_debug.test98
-rw-r--r--storage/innobase/row/row0ins.cc17
5 files changed, 202 insertions, 18 deletions
diff --git a/mysql-test/suite/galera/r/galera_fk_cascade_delete.result b/mysql-test/suite/galera/r/galera_fk_cascade_delete.result
index 291d641db88..16db26c3c6b 100644
--- a/mysql-test/suite/galera/r/galera_fk_cascade_delete.result
+++ b/mysql-test/suite/galera/r/galera_fk_cascade_delete.result
@@ -1,5 +1,10 @@
connection node_2;
connection node_1;
+#
+# test phase with cascading foreign key through 3 tables
+#
+connection node_1;
+set wsrep_sync_wait=0;
CREATE TABLE grandparent (
id INT NOT NULL PRIMARY KEY
) ENGINE=InnoDB;
@@ -21,14 +26,15 @@ INSERT INTO grandparent VALUES (1),(2);
INSERT INTO parent VALUES (1,1), (2,2);
INSERT INTO child VALUES (1,1), (2,2);
connection node_2;
+set wsrep_sync_wait=0;
DELETE FROM grandparent WHERE id = 1;
connection node_1;
-SELECT COUNT(*) = 0 FROM parent WHERE grandparent_id = 1;
-COUNT(*) = 0
-1
-SELECT COUNT(*) = 0 FROM child WHERE parent_id = 1;
-COUNT(*) = 0
-1
+SELECT COUNT(*), COUNT(*) = 0 FROM parent WHERE grandparent_id = 1;
+COUNT(*) COUNT(*) = 0
+0 1
+SELECT COUNT(*), COUNT(*) = 0 FROM child WHERE parent_id = 1;
+COUNT(*) COUNT(*) = 0
+0 1
DROP TABLE child;
DROP TABLE parent;
DROP TABLE grandparent;
diff --git a/mysql-test/suite/galera/r/galera_fk_cascade_delete_debug.result b/mysql-test/suite/galera/r/galera_fk_cascade_delete_debug.result
new file mode 100644
index 00000000000..33ae66b1989
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_fk_cascade_delete_debug.result
@@ -0,0 +1,69 @@
+connection node_2;
+connection node_1;
+#
+# test phase with foreign key of varchar type
+#
+connection node_1;
+CREATE TABLE parent (
+`id` varchar(36) COLLATE utf8_unicode_ci NOT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+CREATE TABLE child (
+`id` int NOT NULL,
+`parent_id` varchar(36) COLLATE utf8_unicode_ci DEFAULT NULL,
+PRIMARY KEY (`id`),
+KEY `parent_id` (`parent_id`),
+CONSTRAINT `ipallocations_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+INSERT INTO parent VALUES ('row one'), ('row two');
+INSERT INTO child VALUES (1,'row one'), (2,'row two');
+connection node_2;
+DELETE FROM parent;
+connection node_1;
+SELECT COUNT(*), COUNT(*) = 0 FROM parent;
+COUNT(*) COUNT(*) = 0
+0 1
+SELECT COUNT(*), COUNT(*) = 0 FROM child;
+COUNT(*) COUNT(*) = 0
+0 1
+DROP TABLE child;
+DROP TABLE parent;
+#
+# test phase with MM conflict in FK cascade
+#
+connection node_1;
+set wsrep_retry_autocommit=0;
+CREATE TABLE parent (
+id INT NOT NULL PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TABLE child (
+id INT NOT NULL PRIMARY KEY,
+j int default 0,
+parent_id INT,
+FOREIGN KEY (parent_id)
+REFERENCES parent(id)
+ON DELETE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO parent VALUES (1);
+INSERT INTO child VALUES (1,0,1);
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb";
+connection node_2;
+DELETE FROM parent;
+connection node_1a;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+connection node_1;
+update child set j=2;;
+connection node_1a;
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+SET GLOBAL debug_dbug = "";
+SET DEBUG_SYNC = "RESET";
+connection node_1;
+SELECT COUNT(*), COUNT(*) = 0 FROM parent;
+COUNT(*) COUNT(*) = 0
+0 1
+SELECT COUNT(*), COUNT(*) = 0 FROM child;
+COUNT(*) COUNT(*) = 0
+0 1
+DROP TABLE child;
+DROP TABLE parent;
diff --git a/mysql-test/suite/galera/t/galera_fk_cascade_delete.test b/mysql-test/suite/galera/t/galera_fk_cascade_delete.test
index 9b79b4c30b6..6f0de0a1f4a 100644
--- a/mysql-test/suite/galera/t/galera_fk_cascade_delete.test
+++ b/mysql-test/suite/galera/t/galera_fk_cascade_delete.test
@@ -3,7 +3,13 @@
#
--source include/galera_cluster.inc
---source include/have_innodb.inc
+
+--echo #
+--echo # test phase with cascading foreign key through 3 tables
+--echo #
+
+--connection node_1
+set wsrep_sync_wait=0;
CREATE TABLE grandparent (
id INT NOT NULL PRIMARY KEY
@@ -30,11 +36,17 @@ INSERT INTO parent VALUES (1,1), (2,2);
INSERT INTO child VALUES (1,1), (2,2);
--connection node_2
+set wsrep_sync_wait=0;
+
+--let $wait_condition = SELECT COUNT(*) = 2 FROM child;
+--source include/wait_condition.inc
DELETE FROM grandparent WHERE id = 1;
--connection node_1
-SELECT COUNT(*) = 0 FROM parent WHERE grandparent_id = 1;
-SELECT COUNT(*) = 0 FROM child WHERE parent_id = 1;
+--let $wait_condition = SELECT COUNT(*) = 1 FROM child;
+--source include/wait_condition.inc
+SELECT COUNT(*), COUNT(*) = 0 FROM parent WHERE grandparent_id = 1;
+SELECT COUNT(*), COUNT(*) = 0 FROM child WHERE parent_id = 1;
DROP TABLE child;
DROP TABLE parent;
diff --git a/mysql-test/suite/galera/t/galera_fk_cascade_delete_debug.test b/mysql-test/suite/galera/t/galera_fk_cascade_delete_debug.test
new file mode 100644
index 00000000000..f38c028b7d6
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_fk_cascade_delete_debug.test
@@ -0,0 +1,98 @@
+--source include/galera_cluster.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--echo #
+--echo # test phase with foreign key of varchar type
+--echo #
+--connection node_1
+ CREATE TABLE parent (
+ `id` varchar(36) COLLATE utf8_unicode_ci NOT NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+
+ CREATE TABLE child (
+ `id` int NOT NULL,
+ `parent_id` varchar(36) COLLATE utf8_unicode_ci DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `parent_id` (`parent_id`),
+ CONSTRAINT `ipallocations_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+
+INSERT INTO parent VALUES ('row one'), ('row two');
+INSERT INTO child VALUES (1,'row one'), (2,'row two');
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM child;
+--source include/wait_condition.inc
+DELETE FROM parent;
+
+--connection node_1
+--let $wait_condition = SELECT COUNT(*) = 0 FROM child;
+--source include/wait_condition.inc
+
+SELECT COUNT(*), COUNT(*) = 0 FROM parent;
+SELECT COUNT(*), COUNT(*) = 0 FROM child;
+
+DROP TABLE child;
+DROP TABLE parent;
+
+--echo #
+--echo # test phase with MM conflict in FK cascade
+--echo #
+
+--connection node_1
+set wsrep_retry_autocommit=0;
+CREATE TABLE parent (
+ id INT NOT NULL PRIMARY KEY
+) ENGINE=InnoDB;
+
+CREATE TABLE child (
+ id INT NOT NULL PRIMARY KEY,
+ j int default 0,
+ parent_id INT,
+ FOREIGN KEY (parent_id)
+ REFERENCES parent(id)
+ ON DELETE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO parent VALUES (1);
+INSERT INTO child VALUES (1,0,1);
+
+# block applier before applying
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb";
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM child;
+--source include/wait_condition.inc
+DELETE FROM parent;
+
+--connection node_1a
+# wait until applier has reached the sync point
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+
+
+--connection node_1
+# issue conflicting write to child table, it should fail in certification
+--error ER_LOCK_DEADLOCK
+--send update child set j=2;
+
+--connection node_1a
+# release the applier
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+SET GLOBAL debug_dbug = "";
+SET DEBUG_SYNC = "RESET";
+
+--connection node_1
+--reap
+
+--let $wait_condition = SELECT COUNT(*) = 0 FROM child;
+--source include/wait_condition.inc
+SELECT COUNT(*), COUNT(*) = 0 FROM parent;
+SELECT COUNT(*), COUNT(*) = 0 FROM child;
+
+DROP TABLE child;
+DROP TABLE parent;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 9a70f749041..3a2460a6b3f 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1378,21 +1378,20 @@ row_ins_foreign_check_on_constraint(
btr_pcur_store_position(cascade->pcur, mtr);
}
+#ifdef WITH_WSREP
+ err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index,
+ FALSE, WSREP_SERVICE_KEY_EXCLUSIVE);
+ if (err != DB_SUCCESS) {
+ ib::info() << "WSREP: foreign key append failed: " << err;
+ goto nonstandard_exit_func;
+ }
+#endif /* WITH_WSREP */
mtr_commit(mtr);
ut_a(cascade->pcur->rel_pos == BTR_PCUR_ON);
cascade->state = UPD_NODE_UPDATE_CLUSTERED;
-#ifdef WITH_WSREP
- err = wsrep_append_foreign_key(trx, foreign, cascade->pcur->old_rec,
- clust_index,
- FALSE, WSREP_SERVICE_KEY_EXCLUSIVE);
- if (err != DB_SUCCESS) {
- fprintf(stderr,
- "WSREP: foreign key append failed: %d\n", err);
- } else
-#endif /* WITH_WSREP */
err = row_update_cascade_for_mysql(thr, cascade,
foreign->foreign_table);