Skip to content

Commit

Permalink
Merge pull request #1163 from georgelorchpercona/ps-5.7-MYR-15
Browse files Browse the repository at this point in the history
Ps 5.7 myr 15
  • Loading branch information
georgelorchpercona committed Nov 22, 2016
2 parents 4ef8371 + 03452ef commit dd290a6
Show file tree
Hide file tree
Showing 29 changed files with 1,892 additions and 545 deletions.
26 changes: 26 additions & 0 deletions mysql-test/include/gap_lock_error_all.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--source include/gap_lock_error_init.inc

let $select_lock=for update;
let $autocommit = 0;
--source include/gap_lock_error_select.inc
let $autocommit = 1;
--source include/gap_lock_error_select.inc

let $select_lock=lock in share mode;
let $autocommit = 0;
--source include/gap_lock_error_select.inc
let $autocommit = 1;
--source include/gap_lock_error_select.inc

let $select_lock=;
let $autocommit = 0;
--source include/gap_lock_error_select.inc
let $autocommit = 1;
--source include/gap_lock_error_select.inc

let $autocommit = 0;
--source include/gap_lock_error_update.inc
let $autocommit = 1;
--source include/gap_lock_error_update.inc

--source include/gap_lock_error_cleanup.inc
1 change: 1 addition & 0 deletions mysql-test/include/gap_lock_error_cleanup.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
drop table gap1, gap2, gap3, gap4;
24 changes: 24 additions & 0 deletions mysql-test/include/gap_lock_error_init.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
eval CREATE TABLE gap1 (id1 INT, id2 INT, id3 INT, c1 INT, value INT,
PRIMARY KEY (id1, id2, id3),
INDEX i (c1)) ENGINE=$engine;
CREATE TABLE gap2 like gap1;
eval CREATE TABLE gap3 (id INT, value INT,
PRIMARY KEY (id),
UNIQUE KEY ui(value)) ENGINE=$engine;
eval CREATE TABLE gap4 (id INT, value INT,
PRIMARY KEY (id)) ENGINE=$engine
PARTITION BY HASH(id) PARTITIONS 2;
--disable_query_log
let $max = 1000;
let $i = 1;
while ($i <= $max) {
eval INSERT INTO gap1 (id1, id2, id3, c1, value)
VALUES ($i div 2, $i div 10, $i, $i, $i);
eval INSERT INTO gap2 (id1, id2, id3, c1, value)
VALUES ($i div 2, $i div 10, $i, $i, $i);
inc $i;
}
--enable_query_log

insert into gap3 values (1,1), (2,2),(3,3),(4,4),(5,5);
insert into gap4 values (1,1), (2,2),(3,3),(4,4),(5,5);
89 changes: 89 additions & 0 deletions mysql-test/include/gap_lock_error_select.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
eval set session autocommit=$autocommit;
let $is_gaplock_target = `SELECT @@autocommit = 0 && '$select_lock' != '' && '$expect_gap_lock_errors' = 1`;

if ($is_gaplock_target)
{
# rnd_init
--error ER_UNKNOWN_ERROR
eval select * from gap1 limit 1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 where value != 100 limit 1 $select_lock;
# index_read_map
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 and id2= 1 $select_lock;
# read_range_first
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 and id2= 1 and id3 != 1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 and id2= 1 and id3
between 1 and 3 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 and id2= 1 order by id3 asc
limit 1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 where id1=1 and id2= 1 order by id3 desc
limit 1 $select_lock;
# index_first
--error ER_UNKNOWN_ERROR
eval select * from gap1 order by id1 asc limit 1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 order by id1 asc, id2 asc, id3 asc limit 1 $select_lock;
# index_last
--error ER_UNKNOWN_ERROR
eval select * from gap1 order by id1 desc limit 1 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap1 order by id1 desc, id2 desc, id3 desc
limit 1 $select_lock;
# secondary index lookup
--error ER_UNKNOWN_ERROR
eval select * from gap1 force index(i) where c1=1 $select_lock;
# unique index lookup, ensure no gap lock errors as this is effectively a
# single point select that does not lock ranges or gaps of keys
eval select * from gap3 force index(ui) where value=1 $select_lock;
# primary key lookup, ensure no gap lock errors as these are effectively
# single point selects that do not lock ranges or gaps of keys
eval select * from gap1 where id1=1 and id2=1 and id3=1 $select_lock;
eval select * from gap1 where id1=1 and id2=1 and id3 in (1, 2, 3) $select_lock;
eval select * from gap1 where id1=1 and id2=1 and id3=1 and value=1
order by c1 $select_lock;
eval select * from gap3 where id=1 $select_lock;
eval select * from gap4 where id=1 $select_lock;
eval select * from gap4 where id in (1, 2, 3) $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap4 $select_lock;
--error ER_UNKNOWN_ERROR
eval select * from gap4 where id between 3 and 7 $select_lock;
}

if (!$is_gaplock_target)
{
eval select * from gap1 limit 1 $select_lock;
eval select * from gap1 where value != 100 limit 1 $select_lock;
eval select * from gap1 where id1=1 $select_lock;
eval select * from gap1 where id1=1 and id2= 1 $select_lock;
eval select * from gap1 where id1=1 and id2= 1 and id3 != 1 $select_lock;
eval select * from gap1 where id1=1 and id2= 1 and id3
between 1 and 3 $select_lock;
eval select * from gap1 where id1=1 and id2= 1 order by id3 asc
limit 1 $select_lock;
eval select * from gap1 where id1=1 and id2= 1 order by id3 desc
limit 1 $select_lock;
eval select * from gap1 order by id1 asc limit 1 $select_lock;
eval select * from gap1 order by id1 asc, id2 asc, id3 asc limit 1 $select_lock;
eval select * from gap1 order by id1 desc limit 1 $select_lock;
eval select * from gap1 order by id1 desc, id2 desc, id3 desc
limit 1 $select_lock;
eval select * from gap1 force index(i) where c1=1 $select_lock;
eval select * from gap3 force index(ui) where value=1 $select_lock;
eval select * from gap1 where id1=1 and id2=1 and id3=1 $select_lock;
eval select * from gap1 where id1=1 and id2=1 and id3 in (1, 2, 3) $select_lock;
eval select * from gap1 where id1=1 and id2=1 and id3=1 and value=1
order by c1 $select_lock;
eval select * from gap3 where id=1 $select_lock;
eval select * from gap4 where id=1 $select_lock;
eval select * from gap4 where id in (1, 2, 3) $select_lock;
eval select * from gap4 $select_lock;
eval select * from gap4 where id between 3 and 7 $select_lock;
}
91 changes: 91 additions & 0 deletions mysql-test/include/gap_lock_error_update.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
eval set session autocommit=$autocommit;
let $is_gaplock_target = `SELECT @@autocommit = 0 && '$expect_gap_lock_errors' = 1`;

if ($is_gaplock_target)
{
## single-table insert,update,delete
insert into gap1 (id1, id2, id3) values (-1,-1,-1);
insert into gap1 (id1, id2, id3) values (-1,-1,-1)
on duplicate key update value=100;
--error ER_UNKNOWN_ERROR
update gap1 set value=100 where id1=1;
update gap1 set value=100 where id1=1 and id2=1 and id3=1;
--error ER_UNKNOWN_ERROR
delete from gap1 where id1=2;
delete from gap1 where id1=-1 and id2=-1 and id3=-1;
commit;

## multi-table statements (preventing all gap locks with autocommit)
# insert into select
--error ER_UNKNOWN_ERROR
insert into gap2 select * from gap1;
--error ER_UNKNOWN_ERROR
insert into gap2 select * from gap1 where id1=1;
insert into gap2 select * from gap1 where id1=1 and id2=1 and id3=1;

# create table select
create table t4 select * from gap1 where id1=1 and id2=1 and id3=1;
drop table t4;
--error ER_UNKNOWN_ERROR
create table t4 select * from gap1;
--error ER_UNKNOWN_ERROR
create table t4 select * from gap1 where id1=1;

# update join
update gap1 join gap2 on gap1.id1 and gap1.id2=gap2.id2 set gap1.value=100 where gap2.id1=3
and gap2.id2=3 and gap2.id3=3;
--error ER_UNKNOWN_ERROR
update gap1 join gap2 on gap1.id1 and gap1.id2=gap2.id2 set gap1.value=100 where gap2.id1=3;
--error ER_UNKNOWN_ERROR
update gap1 join gap2 on gap1.id1 and gap1.id2=gap2.id2 join gap3 on gap1.id1=gap3.id
set gap1.value=100 where gap2.id1=3;
--error ER_UNKNOWN_ERROR
update gap1 set gap1.value= (select count(*) from gap2);

# delete join
delete gap1 from gap1 join gap2 on gap1.id1 and gap1.id2=gap2.id2 where gap2.id1=3
and gap2.id2=3 and gap2.id3=3;
--error ER_UNKNOWN_ERROR
delete gap1 from gap1 join gap2 on gap1.id1 and gap1.id2=gap2.id2 where gap2.id1=3;

# select join / self join
--error ER_UNKNOWN_ERROR
select * from gap1, gap2 limit 1 for update;
--error ER_UNKNOWN_ERROR
select * from gap1 a, gap1 b limit 1 for update;

# unique secondary key
create table u1(
c1 int,
c2 int,
c3 int,
c4 int,
primary key (c1, c2, c3),
unique key (c3, c1)
);
begin;
insert into u1 values (1,1,1,1);
commit;
begin;
insert into u1 values (1,2,1,1) on duplicate key update c4=10;
commit;
begin;
select * from u1 where c3=1 and c1 = 1 for update;
--error ER_UNKNOWN_ERROR
select * from u1 where c3=1 for update;
commit;
drop table u1;
}

if (!$is_gaplock_target)
{
# autocommit doesn't prevent single table operations
insert into gap1 (id1, id2, id3) values (-1,-1,-1);
insert into gap1 (id1, id2, id3) values (-1,-1,-1)
on duplicate key update value=100;
update gap1 set value=100 where id1=1;
update gap1 set value=100 where id1=1 and id2=1 and id3=1;
delete from gap1 where id1=2;
delete from gap1 where id1=-1 and id2=-1 and id3=-1;
commit;
}
20 changes: 20 additions & 0 deletions mysql-test/r/gap_lock_error_memory.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CREATE TABLE gap1 (id1 INT, id2 INT, id3 INT, c1 INT, value INT,
PRIMARY KEY (id1, id2, id3),
INDEX i (c1)) ENGINE=memory;
CREATE TABLE gap2 like gap1;
CREATE TABLE gap3 (id INT, value INT,
PRIMARY KEY (id),
UNIQUE KEY ui(value)) ENGINE=memory;
CREATE TABLE gap4 (id INT, value INT,
PRIMARY KEY (id)) ENGINE=memory
PARTITION BY HASH(id) PARTITIONS 2;
insert into gap3 values (1,1), (2,2),(3,3),(4,4),(5,5);
insert into gap4 values (1,1), (2,2),(3,3),(4,4),(5,5);
select sum(value) from gap1;
sum(value)
500500
update gap1 set gap1.value= (select count(*) from gap2);
select sum(value) from gap1;
sum(value)
1000000
drop table gap1, gap2, gap3, gap4;
20 changes: 20 additions & 0 deletions mysql-test/r/gap_lock_error_myisam.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CREATE TABLE gap1 (id1 INT, id2 INT, id3 INT, c1 INT, value INT,
PRIMARY KEY (id1, id2, id3),
INDEX i (c1)) ENGINE=myisam;
CREATE TABLE gap2 like gap1;
CREATE TABLE gap3 (id INT, value INT,
PRIMARY KEY (id),
UNIQUE KEY ui(value)) ENGINE=myisam;
CREATE TABLE gap4 (id INT, value INT,
PRIMARY KEY (id)) ENGINE=myisam
PARTITION BY HASH(id) PARTITIONS 2;
insert into gap3 values (1,1), (2,2),(3,3),(4,4),(5,5);
insert into gap4 values (1,1), (2,2),(3,3),(4,4),(5,5);
select sum(value) from gap1;
sum(value)
500500
update gap1 set gap1.value= (select count(*) from gap2);
select sum(value) from gap1;
sum(value)
1000000
drop table gap1, gap2, gap3, gap4;

0 comments on commit dd290a6

Please sign in to comment.