Commit 7a1a5e47 authored by sjaakola's avatar sjaakola Committed by Jan Lindström

Refs: MW-369 * fixed sync point usage in MW-369.inc, which made it impossible...

Refs: MW-369 * fixed sync point usage in MW-369.inc, which made it impossible to run this test with --repeat option * moved all MW-369*.test tests into MW-369.test file, each as one separate test phase * added two more test phases, in MW-369.test file * tests MW-369A, MW-369B and MW-369C are obsolete after this commit
parent 0d5c605b
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
SET AUTOCOMMIT=ON;
START TRANSACTION;
DELETE FROM p WHERE f1 = 1;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
INSERT INTO c VALUES (1, 1);
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
COMMIT;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SELECT * FROM p;
f1 f2
1 0
2 0
SELECT * FROM c;
f1 p_id
1 1
DROP TABLE c;
DROP TABLE p;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE p SET f2 = 1 WHERE f1 = 1;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
UPDATE c SET f2 = 1 WHERE f1 = 1;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
COMMIT;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
SELECT * FROM p;
f1 f2
1 1
2 0
SELECT * FROM c;
f1 p_id f2
1 1 1
DROP TABLE c;
DROP TABLE p;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1);
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE p SET f2 = 1 WHERE f1 = 1;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
DELETE FROM c WHERE f1 = 1;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
COMMIT;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
SELECT * FROM p;
f1 f2
1 1
2 0
SELECT * FROM c;
f1 p_id
DROP TABLE c;
DROP TABLE p;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER UNIQUE KEY) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f2)) ;
INSERT INTO p VALUES (1, 0);
SET AUTOCOMMIT=ON;
START TRANSACTION;
UPDATE p SET f2 = 1 WHERE f1 = 1;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
INSERT INTO c VALUES (1, 0);;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
COMMIT;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SELECT * FROM p;
f1 f2
1 0
SELECT * FROM c;
f1 p_id
1 0
DROP TABLE c;
DROP TABLE p;
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)
ON DELETE CASCADE) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
SET AUTOCOMMIT=ON;
START TRANSACTION;
DELETE FROM p WHERE f1 = 1;
SET SESSION wsrep_sync_wait = 0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
UPDATE c SET f2 = 1 WHERE f1 = 1;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
COMMIT;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
SET GLOBAL wsrep_provider_options = 'dbug=';
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SELECT * FROM p;
f1 f2
1 0
2 0
SELECT * FROM c;
f1 p_id f2
1 1 1
DROP TABLE c;
DROP TABLE p;
...@@ -30,7 +30,8 @@ START TRANSACTION; ...@@ -30,7 +30,8 @@ START TRANSACTION;
# #
# Block the $mw_369_child_query from node_2 # Block the $mw_369_child_query from node_2
# #
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 # --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1a
SET SESSION wsrep_sync_wait = 0; SET SESSION wsrep_sync_wait = 0;
--let $galera_sync_point = apply_monitor_slave_enter_sync --let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc --source include/galera_set_sync_point.inc
...@@ -49,6 +50,7 @@ SET SESSION wsrep_sync_wait = 0; ...@@ -49,6 +50,7 @@ SET SESSION wsrep_sync_wait = 0;
--connection node_1a --connection node_1a
--source include/galera_wait_sync_point.inc --source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc --source include/galera_clear_sync_point.inc
--let $galera_sync_point = local_monitor_enter_sync --let $galera_sync_point = local_monitor_enter_sync
--source include/galera_set_sync_point.inc --source include/galera_set_sync_point.inc
...@@ -61,8 +63,13 @@ SET SESSION wsrep_sync_wait = 0; ...@@ -61,8 +63,13 @@ SET SESSION wsrep_sync_wait = 0;
--connection node_1a --connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_enter_sync --let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_enter_sync
--source include/galera_wait_sync_point.inc --source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
#
# both threads are now parked in sync points, signal them to continue
#
--let $galera_sync_point = apply_monitor_slave_enter_sync --let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc --source include/galera_signal_sync_point.inc
--let $galera_sync_point = local_monitor_enter_sync --let $galera_sync_point = local_monitor_enter_sync
--source include/galera_signal_sync_point.inc --source include/galera_signal_sync_point.inc
--source include/galera_clear_sync_point.inc
# #
# This test tests the operation of transaction replay for a transaction which operates on FK parent table. # Test A Outline:
# If a potentially conflicting remote transaction arrives at just the right time during the commit of a # ===============
# local transaction, the local transaction will be aborted and replayed. #
# The replaying should be possible and honor the FK constraints. # This test tests the scenario for MW-369 where a new child table
# row referring to parent table row is inserted concurrently from
# another node while the transaction which tries to delete a
# referred row from the parent table is committing.
#
# The p table will originally have rows (1, 0), (2, 0).
# The c table will be empty.
#
# A new row (1, 1) pointing to parent row (1, 0) is inserted from
# connection node_2, the transaction which tries to remove the
# parent row (1, 0) is run from connection node_1.
#
# Expected outcome:
# ================
#
# The transaction on node_1 will fail. The parent table will contain
# rows (1, 0), (2, 0) and the child table will contain row (1, 1).
# #
--source include/galera_cluster.inc --source include/galera_cluster.inc
...@@ -10,8 +26,6 @@ ...@@ -10,8 +26,6 @@
--source include/have_debug_sync.inc --source include/have_debug_sync.inc
--source suite/galera/include/galera_have_debug_sync.inc --source suite/galera/include/galera_have_debug_sync.inc
--let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ; CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
...@@ -19,64 +33,214 @@ CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, ...@@ -19,64 +33,214 @@ CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
INSERT INTO p VALUES (1, 0); INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0); INSERT INTO p VALUES (2, 0);
--let $mw_369_parent_query = DELETE FROM p WHERE f1 = 1
--let $mw_369_child_query = INSERT INTO c VALUES (1, 1)
#
# we must open connection node_1a here, MW-369.inc will use it later
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--source MW-369.inc
# Commit fails
--connection node_1 --connection node_1
SET AUTOCOMMIT=ON; --error ER_LOCK_DEADLOCK
START TRANSACTION; --reap
DELETE FROM p WHERE f1 = 1; --connection node_2
SELECT * FROM p WHERE f1 = 2 FOR UPDATE; SELECT * FROM p;
SELECT * FROM c;
# Block the commit DROP TABLE c;
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 DROP TABLE p;
--let $galera_sync_point = commit_monitor_enter_sync
--source include/galera_set_sync_point.inc
# #
# insert client row, which will make it impossible to replay the delete on parent # Test B Outline:
# ===============
#
# This test tests the scenario for MW-369 where a existing
# child table row is updated concurrently from another node
# with a transaction which updates the parent table.
#
# The p table will originally have rows (1, 0), (2, 0).
# The c table will originally have rows (1, 1, 0) which points
# to parent table row (1, 0).
#
# Expected outcome:
# ================
#
# Both updates should succeed since they are done to separate tables and
# rows. The parent table will contain rows (1, 1), (2, 0). The child
# table will contain row (1, 1, 1).
# #
--connection node_2
INSERT INTO c values (1,1);
--connection node_1 --connection node_1
--send COMMIT; CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
--let mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
--let $mw_369_child_query = UPDATE c SET f2 = 1 WHERE f1 = 1
--source MW-369.inc
# Commit succeeds
--connection node_1
--reap
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
# Wait until commit is blocked DROP TABLE c;
--connection node_1a DROP TABLE p;
SET SESSION wsrep_sync_wait = 0;
--source include/galera_wait_sync_point.inc
# #
# send conflicting delete which will make node1 trx to abort and replay # Test C Outline:
# ===============
# #
--connection node_2 # This test tests the scenario for MW-369 where a child table row is
DELETE FROM p WHERE f1=2; # deleted concurrently from the other node while a transaction updates
# the parent table referred by the child table row.
#
# The p table will originally have rows (1, 0), (2, 0)
# The c table will originally have row (1, 1) which points to parent
# table row (1, 0).
#
# A row (1, 1) pointing to parent row (1, 0) is deleted from
# connection node_2, the transaction which tries to update the
# parent row (1, 0) is run from connection node_1.
#
# Expected Outcome:
# ================
# Both operations on node_1 and node_2 should succeed without conflicts.
# The parent table should contain values (1, 1), (2, 0) and the child
# table should be empty.
# Wait for both transactions to be blocked --connection node_1
--connection node_1a CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'System lock'; CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
--source include/wait_condition.inc CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)) ;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'init' AND INFO = 'COMMIT'; INSERT INTO p VALUES (1, 0);
--source include/wait_condition.inc INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1);
# Unblock the commit --let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
--connection node_1a --let $mw_369_child_query = DELETE FROM c WHERE f1 = 1
--source include/galera_clear_sync_point.inc --source MW-369.inc
--source include/galera_signal_sync_point.inc
# Commit succeeds # Commit succeeds
--connection node_1 --connection node_1
--reap --reap
# wsrep_local_replays has increased by 1 --connection node_2
--let $wsrep_local_replays_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'` SELECT * FROM p;
--disable_query_log SELECT * FROM c;
--eval SELECT $wsrep_local_replays_new - $wsrep_local_replays_old = 1 AS wsrep_local_replays;
--enable_query_log DROP TABLE c;
DROP TABLE p;
#
# Test D Outline:
# ===============
#
# This test is similar to test A, where parent row is deleted while a child row
# is inserted simultaneously on node 2. However, in this test case the FK
# constraint's target column is a unique key, and parent row is not delete,
# but this key value is changed so that insert on node 2 will cause FK
# violation
#
# The p table will originally have rows (1, 0)
# The c table will originally be empty
#
# in node_1, parent row is updated to value (1,1)
# A row (1, 0) pointing to the old version of parent row (1, 0) is inserted
# in connection node_2
#
# Expected Outcome:
# ================
# This is a true conflict and one transaciton must abort. In this case it is node_1
# transaction, which was scheduled later.
# Parent table should have row (1,0)
# child table should have row (1,0)
#
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER UNIQUE KEY) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f2)) ;
INSERT INTO p VALUES (1, 0);
--let $mw_369_parent_query = UPDATE p SET f2 = 1 WHERE f1 = 1
--let $mw_369_child_query = INSERT INTO c VALUES (1, 0);
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_2
SELECT * FROM p;
SELECT * FROM c;
DROP TABLE c;
DROP TABLE p;
#
# Test E Outline:
# ===============
#
# This test is similar to test B, where parent row is deleted while a child row
# is updated simultaneously on node 2. However, in this test case the FK
# constraint has ON DELETE CASCADE option, and the delete on parent row will
# cascade a delete on child row as well. This will cause true conflict with
# connection node_2, which tries to update unrelated column on child table.
#
# The p table will originally have rows (1, 0), (2,0)
# The c table will originally have row (1,1,0)
#
# in node_1, parent row (1,0) is deleted and cascaded delete will happen on
# child table row (1,1,0).
# in connection node_2 child table row is update to value (1,1,1)
#
# Expected Outcome:
# ================
# This is a true conflict and one transaciton must abort. In this case it is node_1
# transaction, which was scheduled later.
# Parent table should have rows (1,0), (2,0)
# child table should have row (1,1,1)
#
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1)
ON DELETE CASCADE) ;
INSERT INTO p VALUES (1, 0);
INSERT INTO p VALUES (2, 0);
INSERT INTO c VALUES (1, 1, 0);
--let $mw_369_parent_query = DELETE FROM p WHERE f1 = 1
--let $mw_369_child_query = UPDATE c SET f2 = 1 WHERE f1 = 1
--source MW-369.inc
# Commit fails
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_2 --connection node_2
SELECT COUNT(*) = 2 FROM p; SELECT * FROM p;
SELECT COUNT(*) = 1 FROM c; SELECT * FROM c;
DROP TABLE c; DROP TABLE c;
DROP TABLE p; DROP TABLE p;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment