mirror of
https://github.com/MariaDB/server.git
synced 2025-12-13 20:03:16 +03:00
Setting a isolation level of the transaction to read committed
weakens the locks for this session similarly like the option innodb_locks_unsafe_for_binlog. This patch removes almost all gap locking (used in next-key locking) and makes MySQL to release the row locks on the rows which does not belong to result set. Additionally, nonlocking selects on INSERT INTO SELECT, UPDATE ... (SELECT ...), and CREATE ... SELECT ... use a nonlocking consistent read. If a binlog is used, then binlog format should be set to row based binloging to make the execution of the complex SQL statements.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
-- source include/have_innodb.inc
|
||||
#
|
||||
# Note that these tests uses a innodb_locks_unsafe_for_binlog option.
|
||||
#
|
||||
# Note that these tests uses options
|
||||
# innodb_locks_unsafe_for_binlog = true
|
||||
# innodb_lock_timeout = 5
|
||||
|
||||
#
|
||||
# Test cases for a bug #15650
|
||||
#
|
||||
@@ -33,7 +35,7 @@ connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
|
||||
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t1 lock in share mode;
|
||||
@@ -50,6 +52,348 @@ commit;
|
||||
connection b;
|
||||
commit;
|
||||
drop table t1;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
|
||||
#
|
||||
# unlock row test
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
update t1 set b = 5 where b = 1;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
#
|
||||
# X-lock to record (7,3) should be released in a update
|
||||
#
|
||||
select * from t1 where a = 7 and b = 3 for update;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
drop table t1;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
|
||||
|
||||
#
|
||||
# Consistent read should be used in following selects
|
||||
#
|
||||
# 1) INSERT INTO ... SELECT
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (8,6),(12,1),(3,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
insert into t1 select * from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 2) UPDATE ... = ( SELECT ...)
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(d int not null, e int, primary key(d)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
update t1 set b = (select e from t2 where a = d);
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 3) CREATE ... SELECT
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb
|
||||
select * from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Consistent read should not be used if isolation level is serializable
|
||||
#
|
||||
|
||||
# 1) INSERT INTO ... SELECT
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (8,6),(12,1),(3,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--error 1205
|
||||
insert into t1 select * from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 2) UPDATE ... = ( SELECT ...)
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(d int not null, e int, primary key(d)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--error 1205
|
||||
update t1 set b = (select e from t2 where a = d);
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 3) CREATE ... SELECT
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--error 1205
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb
|
||||
select * from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# Consistent read should not be used if locking read is used case
|
||||
# (a) lock in share mode
|
||||
#
|
||||
|
||||
# 1) INSERT INTO ... SELECT
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (8,6),(12,1),(3,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
insert into t1 select * from t2 lock in share mode;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 2) UPDATE ... = ( SELECT ...)
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(d int not null, e int, primary key(d)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
update t1 set b = (select e from t2 where a = d lock in share mode);
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 3) CREATE ... SELECT
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# Consistent read should not be used if locking read is used case
|
||||
# (b) for update
|
||||
#
|
||||
|
||||
# 1) INSERT INTO ... SELECT
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (8,6),(12,1),(3,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
insert into t1 select * from t2 for update;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 2) UPDATE ... = ( SELECT ...)
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t1 values (1,2),(5,3),(4,2);
|
||||
create table t2(d int not null, e int, primary key(d)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
update t1 set b = (select e from t2 where a = d for update);
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# 3) CREATE ... SELECT
|
||||
#
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
create table t2(a int not null, b int, primary key(a)) engine=innodb;
|
||||
insert into t2 values (1,6),(5,1),(4,1);
|
||||
commit;
|
||||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
set autocommit = 0;
|
||||
--error 1205
|
||||
create table t1(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
drop table t2;
|
||||
|
||||
Reference in New Issue
Block a user