# Test for Bug 13867871 - ROW_INS_CHECK_FOREIGN_CONSTRAINT() ACCESSES # FREED DICT_INDEX_T --source include/have_innodb.inc --source include/have_debug_sync.inc # Save the initial number of concurrent sessions. --source include/count_sessions.inc CREATE TABLE parent ( a INT, d INT, b VARCHAR(20), c VARCHAR(75), PRIMARY KEY (a, d, b), INDEX (b, c), INDEX (c)) ENGINE = INNODB; CREATE TABLE child ( a INT, d INT, b VARCHAR(20), c VARCHAR(75), PRIMARY KEY (a, d, b), INDEX (b, c), INDEX (c), FOREIGN KEY (a, d) REFERENCES parent (a, d) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT kukkuu FOREIGN KEY (b, c) REFERENCES parent (b, c) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = INNODB; INSERT INTO parent VALUES (1, 5, 'khD','khD'); SET innodb_lock_wait_timeout=1; connect (con1,localhost,root,,); connection con1; --echo # connection con1: blocked before FOREIGN KEY check during INSERT SET DEBUG_SYNC = 'foreign_constraint_check_for_ins WAIT_FOR drop_done'; --send /* con1 send */ INSERT INTO child VALUES (1, 5, 'khD','khD'); connection default; --echo # connection default: replace the underlying index of FOREIGN KEY let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = 'debug sync point: foreign_constraint_check_for_ins' AND info = '/* con1 send */ INSERT INTO child VALUES (1, 5, ''khD'',''khD'')'; --source include/wait_condition.inc CREATE INDEX idx1 ON parent(b, c); DROP INDEX b ON parent; SET DEBUG_SYNC = 'now SIGNAL drop_done'; connection con1; --echo /* con1 reap */ INSERT INTO child VALUES (1, 5, 'khD','khD'); reap; --echo # connection con1: test ON UPDATE CASCADE BEGIN; SET DEBUG_SYNC = 'foreign_constraint_update_cascade WAIT_FOR create_index'; SET DEBUG_SYNC = 'now SIGNAL start_test'; --send /* con1 send */ DELETE FROM parent WHERE a = 1; connection default; --echo # connection default: con1 already IX-locked table child let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = 'debug sync point: foreign_constraint_update_cascade' AND info = '/* con1 send */ DELETE FROM parent WHERE a = 1'; --source include/wait_condition.inc --error ER_LOCK_DEADLOCK --send /* default send */ CREATE INDEX idx ON child(b, c); connect (con2,localhost,root,,); SET DEBUG_SYNC = 'now WAIT_FOR start_test'; --echo # connection con2: unblock connection default SET DEBUG_SYNC = 'now SIGNAL create_index'; connection default; --echo /* default reap */ CREATE INDEX idx ON child(b, c); --error 0, ER_LOCK_WAIT_TIMEOUT reap; connection con1; --echo /* con1 reap */ DELETE FROM parent WHERE a = 1; reap; connection default; --echo # connection default: con1 is holding IX-lock on table child --error ER_LOCK_WAIT_TIMEOUT CREATE INDEX idx ON child(b, c); --error ER_DROP_INDEX_FK DROP INDEX b ON child; connection con1; --echo # connection con1 COMMIT; connection default; --echo # connection default: no locks on table child CREATE INDEX idx ON child(b, c); DROP INDEX b ON child; SELECT * FROM child; SELECT * FROM parent; connection con1; --echo # connection con1: test ON UPDATE CASCADE INSERT INTO parent VALUES (1, 5, 'khD','khD'); INSERT INTO child VALUES (1, 5, 'khD','khD'); BEGIN; SET DEBUG_SYNC = 'foreign_constraint_check_for_update_done WAIT_FOR alter'; --send /* con1 send */ UPDATE parent SET a = 2; connection default; --echo # connection default: con1 is holding IX-lock on table child let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = 'debug sync point: foreign_constraint_check_for_update_done' AND info = '/* con1 send */ UPDATE parent SET a = 2'; --source include/wait_condition.inc --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx, LOCK=NONE; SET DEBUG_SYNC = 'now SIGNAL alter'; connection con1; --echo /* con1 reap */ UPDATE parent SET a = 2; reap; connection default; --echo # connection default: con1 is holding IX-lock on table child --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx, ALGORITHM=INPLACE; connection con1; --echo # connection con1 ROLLBACK; BEGIN; SET DEBUG_SYNC = 'foreign_constraint_check_for_update WAIT_FOR altered'; SET DEBUG_SYNC = 'now SIGNAL start_test'; --send /* con1 send */ UPDATE parent SET a = 3; connection default; --echo # connection default: con1 is not yet holding locks on table child let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = 'debug sync point: foreign_constraint_check_for_update' AND info = '/* con1 send */ UPDATE parent SET a = 3'; --source include/wait_condition.inc # This should be blocked in commit_inplace_alter_table --send /* default send */ ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx; connection con2; SET DEBUG_SYNC = 'now WAIT_FOR start_test'; --echo # connection con2: unblock connection con1 SET DEBUG_SYNC = 'now SIGNAL altered'; disconnect con2; connection con1; --echo /* con1 reap */ UPDATE parent SET a = 3; reap; connection default; --echo /* default reap */ ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx; # TODO (Bug#14529475): investigate why this is nondeterministic # Progress report: Added a new sync point 'start_test', chtest.sh does # not report problem any more. However, it needs some more confirmation # before this go arounds can be removed. --error 0, ER_LOCK_WAIT_TIMEOUT reap; SELECT * FROM child; connection con1; --echo # connection con1 SELECT * FROM child; COMMIT; disconnect con1; connection default; SELECT * FROM child; SELECT * FROM parent; DROP TABLE child; DROP TABLE parent; SET DEBUG_SYNC = 'RESET'; # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc