Skip to content

Commit 7c07f45

Browse files
temeoJan Lindström
authored andcommitted
MW-369 MTR tests for foreign key conflicts
Tests MW-369C, MW-369D haven't been recorded yet since the outcome from the tests is not what is desired.
1 parent 41fac0a commit 7c07f45

File tree

7 files changed

+323
-0
lines changed

7 files changed

+323
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
2+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
3+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
4+
INSERT INTO p VALUES (1, 0);
5+
INSERT INTO p VALUES (2, 0);
6+
SET AUTOCOMMIT=ON;
7+
START TRANSACTION;
8+
DELETE FROM p WHERE f1 = 1;
9+
SET SESSION wsrep_sync_wait = 0;
10+
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
11+
INSERT INTO c VALUES (1, 1);
12+
SET SESSION wsrep_on = 0;
13+
SET SESSION wsrep_on = 1;
14+
SET GLOBAL wsrep_provider_options = 'dbug=';
15+
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
16+
COMMIT;
17+
SET SESSION wsrep_on = 0;
18+
SET SESSION wsrep_on = 1;
19+
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
20+
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
21+
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
22+
SELECT * FROM p;
23+
f1 f2
24+
1 0
25+
2 0
26+
SELECT * FROM c;
27+
f1 p_id
28+
1 1
29+
DROP TABLE c;
30+
DROP TABLE p;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
2+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
3+
f2 INTEGER,
4+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
5+
INSERT INTO p VALUES (1, 0);
6+
INSERT INTO p VALUES (2, 0);
7+
INSERT INTO c VALUES (1, 1, 0);
8+
SET AUTOCOMMIT=ON;
9+
START TRANSACTION;
10+
UPDATE p SET f2 = 1 WHERE f1 = 1;
11+
SET SESSION wsrep_sync_wait = 0;
12+
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
13+
UPDATE c SET f2 = 1 WHERE f1 = 1;
14+
SET SESSION wsrep_on = 0;
15+
SET SESSION wsrep_on = 1;
16+
SET GLOBAL wsrep_provider_options = 'dbug=';
17+
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
18+
COMMIT;
19+
SET SESSION wsrep_on = 0;
20+
SET SESSION wsrep_on = 1;
21+
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
22+
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
23+
SELECT * FROM p;
24+
f1 f2
25+
1 1
26+
2 0
27+
SELECT * FROM c;
28+
f1 p_id f2
29+
1 1 1
30+
DROP TABLE c;
31+
DROP TABLE p;

mysql-test/suite/galera/t/MW-369.inc

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#
2+
# This file should be included from tests for MW-369 to run concurrent
3+
# transaction from node_1 with autocommit query from node_2.
4+
#
5+
# The parameters:
6+
# * $mw_369_parent_query - the parent query to be run inside transaction
7+
# * $mw_369_child_query - the child query
8+
#
9+
# The operations are the following:
10+
#
11+
# node_1:
12+
# START TRANSACTION;
13+
# $mw_369_parent_query
14+
# node_2
15+
# $mw_369_child_query - will be blocked on node_1 in apply monitor
16+
# node_1:
17+
# COMMIT; - will be blocked on node_1 in local monitor
18+
#
19+
# The $mw_369_child_query is always expected to succeed. The caller is
20+
# responsible for checking if the final COMMIT on connection node_1
21+
# succeeds.
22+
#
23+
24+
--connection node_1
25+
SET AUTOCOMMIT=ON;
26+
START TRANSACTION;
27+
28+
--eval $mw_369_parent_query
29+
30+
#
31+
# Block the $mw_369_child_query from node_2
32+
#
33+
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
34+
SET SESSION wsrep_sync_wait = 0;
35+
--let $galera_sync_point = apply_monitor_slave_enter_sync
36+
--source include/galera_set_sync_point.inc
37+
38+
#
39+
# insert client row, which will make it impossible to replay the
40+
# delete on parent
41+
#
42+
--connection node_2
43+
--eval $mw_369_child_query
44+
45+
#
46+
# Wait until $mw_369_child_query from node_2 reaches the sync point and
47+
# block the 'COMMIT' from node_1 before it certifies.
48+
#
49+
--connection node_1a
50+
--source include/galera_wait_sync_point.inc
51+
--source include/galera_clear_sync_point.inc
52+
--let $galera_sync_point = local_monitor_enter_sync
53+
--source include/galera_set_sync_point.inc
54+
55+
--connection node_1
56+
--send COMMIT
57+
58+
#
59+
# Wait until both sync points have been reached
60+
#
61+
--connection node_1a
62+
--let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_enter_sync
63+
--source include/galera_wait_sync_point.inc
64+
--let $galera_sync_point = apply_monitor_slave_enter_sync
65+
--source include/galera_signal_sync_point.inc
66+
--let $galera_sync_point = local_monitor_enter_sync
67+
--source include/galera_signal_sync_point.inc
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#
2+
# Test Outline:
3+
# ============
4+
#
5+
# This test tests the scenario for MW-369 where a new child table
6+
# row referring to parent table row is inserted concurrently from
7+
# another node while the transaction which tries to delete a
8+
# referred row from the parent table is committing.
9+
#
10+
# The p table will originally have rows (1, 0), (2, 0).
11+
# The c table will be empty.
12+
#
13+
# A new row (1, 1) pointing to parent row (1, 0) is inserted from
14+
# connection node_2, the transaction which tries to remove the
15+
# parent row (1, 0) is run from connection node_1.
16+
#
17+
# Expected outcome:
18+
# ================
19+
#
20+
# The transaction on node_1 will fail. The parent table will contain
21+
# rows (1, 0), (2, 0) and the child table will contain row (1, 1).
22+
#
23+
24+
--source include/galera_cluster.inc
25+
--source include/have_innodb.inc
26+
--source include/have_debug_sync.inc
27+
--source suite/galera/include/galera_have_debug_sync.inc
28+
29+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
30+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
31+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
32+
33+
INSERT INTO p VALUES (1, 0);
34+
INSERT INTO p VALUES (2, 0);
35+
36+
--let $mw_369_parent_query = DELETE FROM p WHERE f1 = 1
37+
--let $mw_369_child_query = INSERT INTO c VALUES (1, 1)
38+
--source MW-369.inc
39+
40+
# Commit fails
41+
--connection node_1
42+
--error ER_LOCK_DEADLOCK
43+
--reap
44+
45+
--connection node_2
46+
SELECT * FROM p;
47+
SELECT * FROM c;
48+
49+
DROP TABLE c;
50+
DROP TABLE p;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#
2+
# Test Outline:
3+
# ============
4+
#
5+
# This test tests the scenario for MW-369 where a existing
6+
# child table row is updated concurrently from another node
7+
# with a transaction which updates the parent table.
8+
#
9+
# The p table will originally have rows (1, 0), (2, 0).
10+
# The c table will originally have rows (1, 1, 0) which points
11+
# to parent table row (1, 0).
12+
#
13+
# Expected outcome:
14+
# ================
15+
#
16+
# Both updates should succeed since they are done to separate tables and
17+
# rows. The parent table will contain rows (1, 1), (2, 0). The child
18+
# table will contain row (1, 1, 1).
19+
#
20+
21+
--source include/galera_cluster.inc
22+
--source include/have_innodb.inc
23+
--source include/have_debug_sync.inc
24+
--source suite/galera/include/galera_have_debug_sync.inc
25+
26+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
27+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
28+
f2 INTEGER,
29+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
30+
31+
INSERT INTO p VALUES (1, 0);
32+
INSERT INTO p VALUES (2, 0);
33+
INSERT INTO c VALUES (1, 1, 0);
34+
35+
--let mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
36+
--let $mw_369_child_query = UPDATE c SET f2 = 1 WHERE f1 = 1
37+
--source MW-369.inc
38+
39+
# Commit succeeds
40+
--connection node_1
41+
--reap
42+
43+
--connection node_2
44+
SELECT * FROM p;
45+
SELECT * FROM c;
46+
47+
DROP TABLE c;
48+
DROP TABLE p;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#
2+
# Test Outline:
3+
# ============
4+
#
5+
# This test tests the scenario for MW-369 where a child table row is
6+
# deleted concurrently from the other node while a transaction updates
7+
# the parent table referred by the child table row.
8+
#
9+
# The p table will originally have rows (1, 0), (2, 0)
10+
# The c table will originally have row (1, 1) which points to parent
11+
# table row (1, 0).
12+
#
13+
# A row (1, 1) pointing to parent row (1, 0) is deleted from
14+
# connection node_2, the transaction which tries to update the
15+
# parent row (1, 0) is run from connection node_1.
16+
#
17+
# Expected Outcome:
18+
# ================
19+
# Both operations on node_1 and node_2 should succeed without conflicts.
20+
# The parent table should contain values (1, 1), (2, 0) and the child
21+
# table should be empty.
22+
23+
--source include/galera_cluster.inc
24+
--source include/have_innodb.inc
25+
--source include/have_debug_sync.inc
26+
--source suite/galera/include/galera_have_debug_sync.inc
27+
28+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
29+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
30+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
31+
32+
INSERT INTO p VALUES (1, 0);
33+
INSERT INTO p VALUES (2, 0);
34+
INSERT INTO c VALUES (1, 1);
35+
36+
--let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
37+
--let $mw_369_child_query = DELETE FROM c WHERE f1 = 1
38+
--source MW-369.inc
39+
40+
# Commit succeeds
41+
--connection node_1
42+
--reap
43+
44+
--connection node_2
45+
SELECT * FROM p;
46+
SELECT * FROM c;
47+
48+
DROP TABLE c;
49+
DROP TABLE p;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#
2+
# Test Outline:
3+
# ============
4+
#
5+
# This test tests the scenario for MW-369 where a child table row is
6+
# inserted concurrently from the other node while a transaction updates
7+
# the parent table referred by the newly inserted child table row.
8+
#
9+
# The p table will originally have rows (1, 0), (2, 0).
10+
# The c table will originally be empty.
11+
#
12+
# A row (1, 1) pointing to parent row (1, 0) is inserted from
13+
# connection node_2, the transaction which tries to update the
14+
# parent row (1, 0) is run from connection node_1.
15+
#
16+
# Expected Outcome:
17+
# ================
18+
# Both operations on node_1 and node_2 should succeed without conflicts.
19+
# The parent table should contain values (1, 1), (2, 0) and the child
20+
# table should contain a row (1, 1)
21+
#
22+
23+
--source include/galera_cluster.inc
24+
--source include/have_innodb.inc
25+
--source include/have_debug_sync.inc
26+
--source suite/galera/include/galera_have_debug_sync.inc
27+
28+
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
29+
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
30+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
31+
32+
INSERT INTO p VALUES (1, 0);
33+
INSERT INTO p VALUES (2, 0);
34+
35+
--let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
36+
--let $mw_369_child_query = INSERT INTO c VALUES (1, 1)
37+
--source MW-369.inc
38+
39+
# Commit succeeds
40+
--connection node_1
41+
--reap
42+
43+
--connection node_2
44+
SELECT * FROM p;
45+
SELECT * FROM c;
46+
47+
DROP TABLE c;
48+
DROP TABLE p;

0 commit comments

Comments
 (0)