diff --git a/mysql-test/innodb_unsafe_binlog-master.opt b/mysql-test/innodb_unsafe_binlog-master.opt new file mode 100644 index 0000000000000000000000000000000000000000..503c8457b2ccdc469d583dc423d6bc6792ba3ee2 --- /dev/null +++ b/mysql-test/innodb_unsafe_binlog-master.opt @@ -0,0 +1 @@ +--innodb_locks_unsafe_for_binlog=true diff --git a/mysql-test/innodb_unsafe_binlog.result b/mysql-test/innodb_unsafe_binlog.result new file mode 100644 index 0000000000000000000000000000000000000000..b806faaf5867f3c6e0831582d2fc8815ccc1e016 --- /dev/null +++ b/mysql-test/innodb_unsafe_binlog.result @@ -0,0 +1,16 @@ +drop table if exists t1,t2; +create table t1 (id int not null, f_id int not null, f int not null, +primary key(f_id, id)) engine=innodb; +create table t2 (id int not null,s_id int not null,s varchar(200), +primary key(id)) engine=innodb; +INSERT INTO t1 VALUES (8, 1, 3); +INSERT INTO t1 VALUES (1, 2, 1); +INSERT INTO t2 VALUES (1, 0, ''); +INSERT INTO t2 VALUES (8, 1, ''); +commit; +DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id) +WHERE mm.id IS NULL; +select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id) +where mm.id is null lock in share mode; +id f_id f +drop table t1,t2; diff --git a/mysql-test/innodb_unsafe_binlog.test b/mysql-test/innodb_unsafe_binlog.test new file mode 100644 index 0000000000000000000000000000000000000000..b7dd156cfb7fb6f6c02bf818859bce412f23b250 --- /dev/null +++ b/mysql-test/innodb_unsafe_binlog.test @@ -0,0 +1,26 @@ +-- source include/have_innodb.inc +# +# Note that these test work only on 5.0 because these test need +# innodb_locks_unsafe_for_binlog option implemented. +# +# +# Test cases for a bug #15650 +# + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (id int not null, f_id int not null, f int not null, +primary key(f_id, id)) engine=innodb; +create table t2 (id int not null,s_id int not null,s varchar(200), +primary key(id)) engine=innodb; +INSERT INTO t1 VALUES (8, 1, 3); +INSERT INTO t1 VALUES (1, 2, 1); +INSERT INTO t2 VALUES (1, 0, ''); +INSERT INTO t2 VALUES (8, 1, ''); +commit; +DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id) +WHERE mm.id IS NULL; +select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id) +where mm.id is null lock in share mode; +drop table t1,t2; diff --git a/row/row0sel.c b/row/row0sel.c index 1b66f14f5d77037732e9a9c8630d4da51f8a190c..ef61de0706e2d155eb8d11582f911c651f739f8e 100644 --- a/row/row0sel.c +++ b/row/row0sel.c @@ -3972,12 +3972,12 @@ cursor lock count is done correctly. See bugs #12263 and #12456! /* We have an optimization to save CPU time: if this is a consistent read on a unique condition on the clustered index, then we do not store the pcur position, because any fetch next or prev will anyway - return 'end of file'. An exception is the MySQL HANDLER command - where the user can move the cursor with PREV or NEXT even after - a unique search. */ + return 'end of file'. Exceptions are locking reads and the MySQL + HANDLER command where the user can move the cursor with PREV or NEXT + even after a unique search. */ if (!unique_search_from_clust_index - || prebuilt->select_lock_type == LOCK_X + || prebuilt->select_lock_type != LOCK_NONE || prebuilt->used_in_HANDLER) { /* Inside an update always store the cursor position */