1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-22180 Planner opens unnecessary tables when updated table is referenced by foreign keys

only MDL-prelock but do not open FK child tables for read-only (RESTRICT)
FK actions.

Tables still needs to be opened for CASCADE actions, see 9180e8666b
This commit is contained in:
Sergei Golubchik
2020-05-05 14:55:05 +02:00
parent 10aaa77509
commit 0fcc3abf4a
3 changed files with 47 additions and 0 deletions

View File

@ -124,3 +124,24 @@ SET debug_sync='reset';
SHOW OPEN TABLES FROM test;
Database Table In_use Name_locked
DROP TABLE t1, t2;
create table t1 (pk int primary key, data int) engine=innodb;
insert t1 values (1,1),(2,2),(3,3);
create table t2 (t1_pk int, foreign key (t1_pk) references t1 (pk)) engine=innodb;
insert t2 values (1),(2);
insert t2 values (10);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_pk`) REFERENCES `t1` (`pk`))
flush tables;
flush status;
update t1 set data=10 where pk+1>10;
show status like '%opened_tab%';
Variable_name Value
Opened_table_definitions 1
Opened_tables 1
flush tables;
flush status;
update t2 set t1_pk=11 where t1_pk+1>10;
show status like '%opened_tab%';
Variable_name Value
Opened_table_definitions 1
Opened_tables 1
drop table t2, t1;

View File

@ -158,3 +158,26 @@ connection default;
SET debug_sync='reset';
SHOW OPEN TABLES FROM test;
DROP TABLE t1, t2;
#
# MDEV-22180 Planner opens unnecessary tables when updated table is referenced by foreign keys
#
source include/have_innodb.inc;
create table t1 (pk int primary key, data int) engine=innodb;
insert t1 values (1,1),(2,2),(3,3);
create table t2 (t1_pk int, foreign key (t1_pk) references t1 (pk)) engine=innodb;
insert t2 values (1),(2);
error ER_NO_REFERENCED_ROW_2;
insert t2 values (10);
flush tables;
flush status;
# with ON UPDATE RESTRICT child tables are not opened
update t1 set data=10 where pk+1>10;
show status like '%opened_tab%';
flush tables;
flush status;
# neither are parent tables
update t2 set t1_pk=11 where t1_pk+1>10;
show status like '%opened_tab%';
drop table t2, t1;