mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +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:
@@ -124,3 +124,24 @@ SET debug_sync='reset';
|
|||||||
SHOW OPEN TABLES FROM test;
|
SHOW OPEN TABLES FROM test;
|
||||||
Database Table In_use Name_locked
|
Database Table In_use Name_locked
|
||||||
DROP TABLE t1, t2;
|
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';
|
SET debug_sync='reset';
|
||||||
SHOW OPEN TABLES FROM test;
|
SHOW OPEN TABLES FROM test;
|
||||||
DROP TABLE t1, t2;
|
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;
|
open_type= routine ? OT_TEMPORARY_OR_BASE : OT_BASE_ONLY;
|
||||||
belong_to_view= belong_to_view_arg;
|
belong_to_view= belong_to_view_arg;
|
||||||
trg_event_map= trg_event_map_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;
|
**last_ptr= this;
|
||||||
prev_global= *last_ptr;
|
prev_global= *last_ptr;
|
||||||
|
Reference in New Issue
Block a user