Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion include/my_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,12 @@ enum ha_extra_function {
/** Finish HA_EXTRA_BEGIN_COPY or HA_EXTRA_BEGIN_ALTER_IGNORE_COPY */
HA_EXTRA_END_COPY,
/** Abort HA_EXTRA_BEGIN_COPY or HA_EXTRA_BEGIN_ALTER_IGNORE_COPY */
HA_EXTRA_ABORT_COPY
HA_EXTRA_ABORT_COPY,
/*
Advise the engine that the next operation will be a full table or
full index scan
*/
HA_EXTRA_FULL_SCAN
};

/* Compatible option, to be deleted in 6.0 */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[row_lock]
--disable_innodb_table_lock_on_full_scan

[table_lock]
--innodb_table_lock_on_full_scan

4 changes: 4 additions & 0 deletions mysql-test/include/innodb_table_lock_on_full_scan.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The goal of including this file is to enable innodb_table_lock_on_full_scan combinations
# (see include/innodb_table_lock_on_full_scan.combinations)

--source include/have_innodb.inc
17 changes: 14 additions & 3 deletions mysql-test/include/innodb_trx_weight.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,23 @@ SELECT * FROM t2 FOR UPDATE;
INSERT INTO t2 VALUES (0);

-- connection con2
INSERT INTO t1 VALUES (0);
if (!$insert_deadlock) {
INSERT INTO t1 VALUES (0);
}
if ($insert_deadlock) {
--error ER_LOCK_DEADLOCK
INSERT INTO t1 VALUES (0);
}
ROLLBACK;

-- connection con1
-- error ER_LOCK_DEADLOCK
-- reap
if (!$insert_deadlock) {
-- error ER_LOCK_DEADLOCK
-- reap
}
if ($insert_deadlock) {
-- reap
}
-- }
# else
-- if (!$con1_should_be_rolledback) {
Expand Down
121 changes: 121 additions & 0 deletions mysql-test/main/innodb_full_scan,table_lock.rdiff
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
--- innodb_full_scan.result
+++ innodb_full_scan,table_lock.result
@@ -10,14 +10,14 @@
42
COMMIT;
# lock_rec_created
-1
+0
BEGIN;
SELECT * FROM t for update;
a
42
COMMIT;
# lock_rec_created
-1
+0
## SELECT without explicit transaction
SELECT * FROM t;
a
@@ -55,13 +55,13 @@
UNION
select * from t1;
# lock_rec_created
-3
+1
insert into t2
select * from t1
UNION
select * from t1 where t1.a = 10;
# lock_rec_created
-3
+1
insert into t2
select * from t1 where t1.a > 10
UNION
@@ -73,7 +73,7 @@
UNION
select * from t1 where t1.a > 10;
# lock_rec_created
-1
+0
drop table t1, t2;
# CREATE ... SELECT with UNION
create table t1 (a int primary key, b int) engine=innodb;
@@ -83,13 +83,13 @@
UNION
select * from t1;
# lock_rec_created
-3
+1
create or replace table t2 (a int, b int) engine=innodb
select * from t1
UNION
select * from t1 where t1.a = 10;
# lock_rec_created
-3
+1
create or replace table t2 (a int, b int) engine=innodb
select * from t1 where t1.a > 10
UNION
@@ -101,14 +101,14 @@
UNION
select * from t1 where t1.a > 10;
# lock_rec_created
-1
+0
drop table t1, t2;
# UPDATE
create table t1 (a int primary key, b int) engine=innodb;
insert into t1 select seq, seq from seq_1_to_100;
UPDATE t1 SET b = b + 3;
# lock_rec_created
-1
+0
UPDATE t1 SET b = b + 3 WHERE a = 10;
# lock_rec_created
1
@@ -118,7 +118,7 @@
# DELETE
DELETE FROM t1;
# lock_rec_created
-1
+0
DELETE FROM t1 WHERE a = 10;
# lock_rec_created
1
@@ -135,7 +135,7 @@
select * from t1 join t2 on t1.a = t2.a LOCK IN SHARE MODE;
commit;
# lock_rec_created
-2
+1
begin;
select * from t1 join t2 on t1.a = t2.b LOCK IN SHARE MODE;
commit;
@@ -145,7 +145,7 @@
select * from t1 join t2 on t1.b = t2.b LOCK IN SHARE MODE;
commit;
# lock_rec_created
-2
+1
drop table t1, t2;
# Full index scan
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
@@ -153,14 +153,14 @@
create table t11(a int) engine=innodb;
insert into t11 select a from t10;
# lock_rec_created
-11
+0
drop table t10, t11;
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
insert into t10 select seq, uuid() from seq_1_to_10000;
create table t11(a int) engine=innodb;
insert into t11 select a from t10 order by a desc;
# lock_rec_created
-11
+0
drop table t10, t11;
# Range access
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
2 changes: 2 additions & 0 deletions mysql-test/main/innodb_full_scan.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--innodb_monitor_enable=lock_rec_lock_created

176 changes: 176 additions & 0 deletions mysql-test/main/innodb_full_scan.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#
# MDEV-24813 Locking full table scan fails to use table-level locking
#
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
insert into t values (42);
# SELECT
BEGIN;
SELECT * FROM t LOCK IN SHARE MODE;
a
42
COMMIT;
# lock_rec_created
1
BEGIN;
SELECT * FROM t for update;
a
42
COMMIT;
# lock_rec_created
1
## SELECT without explicit transaction
SELECT * FROM t;
a
42
# lock_rec_created
0
# SELECT with a condition
BEGIN;
select * from t where a > 10 lock in share mode;
a
42
COMMIT;
# lock_rec_created
1
BEGIN;
SELECT * FROM t where a > 10 for update;
a
42
COMMIT;
# lock_rec_created
1
## SELECT with a condition without explicit transaction
SELECT * FROM t where a > 10;
a
42
# lock_rec_created
0
DROP TABLE t;
# INSERT INTO ... SELECT with UNION
create table t1 (a int primary key, b int) engine=innodb;
insert into t1 select seq, seq from seq_1_to_100;
create table t2 (a int, b int) engine=innodb;
insert into t2
select * from t1 where t1.a = 10
UNION
select * from t1;
# lock_rec_created
3
insert into t2
select * from t1
UNION
select * from t1 where t1.a = 10;
# lock_rec_created
3
insert into t2
select * from t1 where t1.a > 10
UNION
select * from t1;
# lock_rec_created
1
insert into t2
select * from t1
UNION
select * from t1 where t1.a > 10;
# lock_rec_created
1
drop table t1, t2;
# CREATE ... SELECT with UNION
create table t1 (a int primary key, b int) engine=innodb;
insert into t1 select seq, seq from seq_1_to_100;
create table t2 (a int, b int) engine=innodb
select * from t1 where t1.a = 10
UNION
select * from t1;
# lock_rec_created
3
create or replace table t2 (a int, b int) engine=innodb
select * from t1
UNION
select * from t1 where t1.a = 10;
# lock_rec_created
3
create or replace table t2 (a int, b int) engine=innodb
select * from t1 where t1.a > 10
UNION
select * from t1;
# lock_rec_created
1
create or replace table t2 (a int, b int) engine=innodb
select * from t1
UNION
select * from t1 where t1.a > 10;
# lock_rec_created
1
drop table t1, t2;
# UPDATE
create table t1 (a int primary key, b int) engine=innodb;
insert into t1 select seq, seq from seq_1_to_100;
UPDATE t1 SET b = b + 3;
# lock_rec_created
1
UPDATE t1 SET b = b + 3 WHERE a = 10;
# lock_rec_created
1
UPDATE t1 SET b = b + 3 WHERE a > 10;
# lock_rec_created
1
# DELETE
DELETE FROM t1;
# lock_rec_created
1
DELETE FROM t1 WHERE a = 10;
# lock_rec_created
1
DELETE FROM t1 WHERE a > 10;
# lock_rec_created
1
drop table t1;
# JOIN
create table t1 (a int primary key, b int) engine=innodb;
insert into t1 select seq, seq from seq_1_to_100;
create table t2 (a int primary key, b int) engine=innodb;
insert into t2 select seq, seq from seq_1_to_100;
begin;
select * from t1 join t2 on t1.a = t2.a LOCK IN SHARE MODE;
commit;
# lock_rec_created
2
begin;
select * from t1 join t2 on t1.a = t2.b LOCK IN SHARE MODE;
commit;
# lock_rec_created
2
begin;
select * from t1 join t2 on t1.b = t2.b LOCK IN SHARE MODE;
commit;
# lock_rec_created
2
drop table t1, t2;
# Full index scan
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
insert into t10 select seq, uuid() from seq_1_to_10000;
create table t11(a int) engine=innodb;
insert into t11 select a from t10;
# lock_rec_created
11
drop table t10, t11;
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
insert into t10 select seq, uuid() from seq_1_to_10000;
create table t11(a int) engine=innodb;
insert into t11 select a from t10 order by a desc;
# lock_rec_created
11
drop table t10, t11;
# Range access
create table t10 (a int, b varchar(100), index(a)) engine=innodb;
insert into t10 select seq, uuid() from seq_1_to_10000;
create table t11(a int) engine=innodb;
explain
insert into t11 select a from t10 where a > 30;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t10 range a a 5 NULL # Using where; Using index
insert into t11 select a from t10 where a > 30;
# lock_rec_created
11
drop table t10, t11;
Loading