Commit 0fcc3abf authored by Sergei Golubchik's avatar Sergei Golubchik

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 9180e866
parent 10aaa775
......@@ -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;
......@@ -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;
......@@ -1813,6 +1813,9 @@ struct TABLE_LIST
open_type= routine ? OT_TEMPORARY_OR_BASE : OT_BASE_ONLY;
belong_to_view= belong_to_view_arg;
trg_event_map= trg_event_map_arg;
/* MDL is enough for read-only FK checks, we don't need the table */
if (prelocking_placeholder == FK && lock_type < TL_WRITE_ALLOW_WRITE)
open_strategy= OPEN_STUB;
**last_ptr= this;
prev_global= *last_ptr;
......
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