Commit 0029a375 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Bug #44613 SELECT statement inside FUNCTION takes a shared lock

The problem was that a shared InnoDB row lock was taken when executing
SELECT statements inside a stored function as a part of a transaction
using REPEATABLE READ. This prevented other transactions from updating
the row.

InnoDB uses multi-versioning and consistent nonlocking reads. SELECTs
should therefore not acquire locks and block other transactions
wishing to do updates.

This bug is no longer repeatable with the changes introduced in the scope
of metadata locking.

Test case added to innodb_mysql.test.
parent 07923855
......@@ -2297,3 +2297,28 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t1;
#
# Bug#44613 SELECT statement inside FUNCTION takes a shared lock
#
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
CREATE TABLE t1(x INT PRIMARY KEY, y INT) ENGINE=innodb;
INSERT INTO t1 VALUES (1, 0), (2, 0);
CREATE FUNCTION f1(z INT) RETURNS INT READS SQL DATA
RETURN (SELECT x FROM t1 WHERE x = z);
# Connection default
START TRANSACTION;
SELECT f1(1);
f1(1)
1
# Connection con2
START TRANSACTION;
SELECT f1(1);
f1(1)
1
UPDATE t1 SET y = 1 WHERE x = 1;
COMMIT;
# Connection default
COMMIT;
DROP TABLE t1;
DROP FUNCTION f1;
......@@ -555,3 +555,42 @@ create table t2 (fk int, key x (fk),
constraint x foreign key (FK) references t1 (PK)) engine=InnoDB;
show create table t2;
drop table t2, t1;
--echo #
--echo # Bug#44613 SELECT statement inside FUNCTION takes a shared lock
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
CREATE TABLE t1(x INT PRIMARY KEY, y INT) ENGINE=innodb;
INSERT INTO t1 VALUES (1, 0), (2, 0);
CREATE FUNCTION f1(z INT) RETURNS INT READS SQL DATA
RETURN (SELECT x FROM t1 WHERE x = z);
--echo # Connection default
START TRANSACTION;
SELECT f1(1);
--echo # Connection con2
--disable_query_log
connect (con2, localhost, root);
--enable_query_log
START TRANSACTION;
SELECT f1(1);
# This next statement used to block.
UPDATE t1 SET y = 1 WHERE x = 1;
COMMIT;
disconnect con2;
--source include/wait_until_disconnected.inc
--echo # Connection default
connection default;
COMMIT;
DROP TABLE t1;
DROP FUNCTION f1;
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