mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
MDEV-13331 FK DELETE CASCADE does not honor innodb_lock_wait_timeout
row_ins_check_foreign_constraint(): On timeout,
return DB_LOCK_WAIT_TIMEOUT instead of DB_LOCK_WAIT,
so that the lock wait will be properly terminated.
Also, replace some redundant assignments.
It looks like this bug was introduced in MySQL 5.7.8 by:
commit a97f6b91227c7e0fc3151cfe5421891e79c12d19
Author: Annamalai Gurusami <annamalai.gurusami@oracle.com>
Date: Tue Jun 9 16:02:31 2015 +0530
Bug #20953265 INNODB: FAILING ASSERTION: RESULT != FTS_INVALID
This commit is contained in:
parent
2f342c4507
commit
5d1c0d0086
3 changed files with 90 additions and 28 deletions
|
|
@ -209,7 +209,6 @@ UPDATE users SET name = 'qux' WHERE id = 1;
|
|||
connect con1,localhost,root,,;
|
||||
SET innodb_lock_wait_timeout= 1;
|
||||
DELETE FROM matchmaking_groups WHERE id = 10;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
COMMIT;
|
||||
SELECT * FROM matchmaking_group_users WHERE matchmaking_group_id NOT IN (SELECT id FROM matchmaking_groups);
|
||||
|
|
@ -222,3 +221,45 @@ id name
|
|||
2 bar
|
||||
DROP TABLE
|
||||
matchmaking_group_maps, matchmaking_group_users, matchmaking_groups, users;
|
||||
#
|
||||
# MDEV-13331 FK DELETE CASCADE does not honor innodb_lock_wait_timeout
|
||||
#
|
||||
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (
|
||||
id INT NOT NULL PRIMARY KEY,
|
||||
ref_id INT NOT NULL DEFAULT 0,
|
||||
f INT NULL,
|
||||
FOREIGN KEY (ref_id) REFERENCES t1 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
INSERT INTO t2 VALUES (1,1,10),(2,2,20);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`id` int(11) NOT NULL,
|
||||
`ref_id` int(11) NOT NULL DEFAULT 0,
|
||||
`f` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ref_id` (`ref_id`),
|
||||
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`ref_id`) REFERENCES `t1` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
connection con1;
|
||||
BEGIN;
|
||||
UPDATE t2 SET f = 11 WHERE id = 1;
|
||||
connection default;
|
||||
SET innodb_lock_wait_timeout= 1;
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
connection con1;
|
||||
COMMIT;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
SELECT * FROM t2;
|
||||
id ref_id f
|
||||
1 1 11
|
||||
2 2 20
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
SELECT * FROM t2;
|
||||
id ref_id f
|
||||
2 2 20
|
||||
DROP TABLE t2, t1;
|
||||
|
|
|
|||
|
|
@ -186,7 +186,6 @@ UPDATE users SET name = 'qux' WHERE id = 1;
|
|||
--connect (con1,localhost,root,,)
|
||||
SET innodb_lock_wait_timeout= 1;
|
||||
DELETE FROM matchmaking_groups WHERE id = 10;
|
||||
--disconnect con1
|
||||
|
||||
--connection default
|
||||
COMMIT;
|
||||
|
|
@ -200,4 +199,41 @@ SELECT * FROM users;
|
|||
DROP TABLE
|
||||
matchmaking_group_maps, matchmaking_group_users, matchmaking_groups, users;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-13331 FK DELETE CASCADE does not honor innodb_lock_wait_timeout
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id INT NOT NULL PRIMARY KEY,
|
||||
ref_id INT NOT NULL DEFAULT 0,
|
||||
f INT NULL,
|
||||
FOREIGN KEY (ref_id) REFERENCES t1 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
INSERT INTO t2 VALUES (1,1,10),(2,2,20);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
--connection con1
|
||||
BEGIN;
|
||||
UPDATE t2 SET f = 11 WHERE id = 1;
|
||||
|
||||
--connection default
|
||||
SET innodb_lock_wait_timeout= 1;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
|
||||
--connection con1
|
||||
COMMIT;
|
||||
--disconnect con1
|
||||
|
||||
--connection default
|
||||
SELECT * FROM t2;
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
|
|
|||
|
|
@ -1759,13 +1759,6 @@ row_ins_check_foreign_constraint(
|
|||
cmp = cmp_dtuple_rec(entry, rec, offsets);
|
||||
|
||||
if (cmp == 0) {
|
||||
|
||||
ulint lock_type;
|
||||
|
||||
lock_type = skip_gap_lock
|
||||
? LOCK_REC_NOT_GAP
|
||||
: LOCK_ORDINARY;
|
||||
|
||||
if (rec_get_deleted_flag(rec,
|
||||
rec_offs_comp(offsets))) {
|
||||
/* In delete-marked records, DB_TRX_ID must
|
||||
|
|
@ -1775,7 +1768,9 @@ row_ins_check_foreign_constraint(
|
|||
offsets));
|
||||
|
||||
err = row_ins_set_shared_rec_lock(
|
||||
lock_type, block,
|
||||
skip_gap_lock
|
||||
? LOCK_REC_NOT_GAP
|
||||
: LOCK_ORDINARY, block,
|
||||
rec, check_index, offsets, thr);
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
|
|
@ -1857,23 +1852,21 @@ row_ins_check_foreign_constraint(
|
|||
} else {
|
||||
ut_a(cmp < 0);
|
||||
|
||||
err = DB_SUCCESS;
|
||||
|
||||
if (!skip_gap_lock) {
|
||||
err = row_ins_set_shared_rec_lock(
|
||||
err = skip_gap_lock
|
||||
? DB_SUCCESS
|
||||
: row_ins_set_shared_rec_lock(
|
||||
LOCK_GAP, block,
|
||||
rec, check_index, offsets, thr);
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
/* fall through */
|
||||
case DB_SUCCESS:
|
||||
if (check_ref) {
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1921,19 +1914,11 @@ do_possible_lock_wait:
|
|||
|
||||
thr->lock_state = QUE_THR_LOCK_NOLOCK;
|
||||
|
||||
DBUG_PRINT("to_be_dropped",
|
||||
("table: %s", check_table->name.m_name));
|
||||
if (check_table->to_be_dropped) {
|
||||
/* The table is being dropped. We shall timeout
|
||||
this operation */
|
||||
err = DB_LOCK_WAIT_TIMEOUT;
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
err = check_table->to_be_dropped
|
||||
? DB_LOCK_WAIT_TIMEOUT
|
||||
: trx->error_state;
|
||||
}
|
||||
|
||||
|
||||
exit_func:
|
||||
if (heap != NULL) {
|
||||
mem_heap_free(heap);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue