|
|
|
@ -70,6 +70,161 @@ commit; |
|
|
|
set autocommit=default; |
|
|
|
drop table t1; |
|
|
|
|
|
|
|
--echo # |
|
|
|
--echo # Bug#41756 Strange error messages about locks from InnoDB |
|
|
|
--echo # |
|
|
|
--disable_warnings |
|
|
|
drop table if exists t1; |
|
|
|
--enable_warnings |
|
|
|
--echo # In the default transaction isolation mode, and/or with |
|
|
|
--echo # innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row() |
|
|
|
--echo # in InnoDB does nothing. |
|
|
|
--echo # Thus in order to reproduce the condition that led to the |
|
|
|
--echo # warning, one needs to relax isolation by either |
|
|
|
--echo # setting a weaker tx_isolation value, or by turning on |
|
|
|
--echo # the unsafe replication switch. |
|
|
|
--echo # For testing purposes, choose to tweak the isolation level, |
|
|
|
--echo # since it's settable at runtime, unlike |
|
|
|
--echo # innodb_locks_unsafe_for_binlog, which is |
|
|
|
--echo # only a command-line switch. |
|
|
|
--echo # |
|
|
|
set @@session.tx_isolation="read-committed"; |
|
|
|
|
|
|
|
--echo # Prepare data. We need a table with a unique index, |
|
|
|
--echo # for join_read_key to be used. The other column |
|
|
|
--echo # allows to control what passes WHERE clause filter. |
|
|
|
create table t1 (a int primary key, b int) engine=innodb; |
|
|
|
--echo # Let's make sure t1 has sufficient amount of rows |
|
|
|
--echo # to exclude JT_ALL access method when reading it, |
|
|
|
--echo # i.e. make sure that JT_EQ_REF(a) is always preferred. |
|
|
|
insert into t1 values (1,1), (2,null), (3,1), (4,1), |
|
|
|
(5,1), (6,1), (7,1), (8,1), (9,1), (10,1), |
|
|
|
(11,1), (12,1), (13,1), (14,1), (15,1), |
|
|
|
(16,1), (17,1), (18,1), (19,1), (20,1); |
|
|
|
--echo # |
|
|
|
--echo # Demonstrate that for the SELECT statement |
|
|
|
--echo # used later in the test JT_EQ_REF access method is used. |
|
|
|
--echo # |
|
|
|
--vertical_results |
|
|
|
explain |
|
|
|
select 1 from t1 natural join (select 2 as a, 1 as b union all |
|
|
|
select 2 as a, 2 as b) as t2 for update; |
|
|
|
--horizontal_results |
|
|
|
--echo # |
|
|
|
--echo # Demonstrate that the reported SELECT statement |
|
|
|
--echo # no longer produces warnings. |
|
|
|
--echo # |
|
|
|
select 1 from t1 natural join (select 2 as a, 1 as b union all |
|
|
|
select 2 as a, 2 as b) as t2 for update; |
|
|
|
commit; |
|
|
|
--echo # |
|
|
|
--echo # Demonstrate that due to lack of inter-sweep "reset" function, |
|
|
|
--echo # we keep some non-matching records locked, even though we know |
|
|
|
--echo # we could unlock them. |
|
|
|
--echo # To do that, show that if there is only one distinct value |
|
|
|
--echo # for a in t2 (a=2), we will keep record (2,null) in t1 locked. |
|
|
|
--echo # But if we add another value for "a" to t2, say 6, |
|
|
|
--echo # join_read_key cache will be pruned at least once, |
|
|
|
--echo # and thus record (2, null) in t1 will get unlocked. |
|
|
|
--echo # |
|
|
|
begin; |
|
|
|
select 1 from t1 natural join (select 2 as a, 1 as b union all |
|
|
|
select 2 as a, 2 as b) as t2 for update; |
|
|
|
connect (con1,localhost,root,,); |
|
|
|
--echo # |
|
|
|
--echo # Switching to connection con1 |
|
|
|
connection con1; |
|
|
|
--echo # We should be able to delete all records from t1 except (2, null), |
|
|
|
--echo # since they were not locked. |
|
|
|
begin; |
|
|
|
--echo # Delete in series of 3 records so that full scan |
|
|
|
--echo # is not used and we're not blocked on record (2,null) |
|
|
|
delete from t1 where a in (1,3,4); |
|
|
|
delete from t1 where a in (5,6,7); |
|
|
|
delete from t1 where a in (8,9,10); |
|
|
|
delete from t1 where a in (11,12,13); |
|
|
|
delete from t1 where a in (14,15,16); |
|
|
|
delete from t1 where a in (17,18); |
|
|
|
delete from t1 where a in (19,20); |
|
|
|
--echo # |
|
|
|
--echo # Record (2, null) is locked. This is actually unnecessary, |
|
|
|
--echo # because the previous select returned no rows. |
|
|
|
--echo # Just demonstrate the effect. |
|
|
|
--echo # |
|
|
|
--error ER_LOCK_WAIT_TIMEOUT |
|
|
|
delete from t1; |
|
|
|
rollback; |
|
|
|
--echo # |
|
|
|
--echo # Switching to connection default |
|
|
|
connection default; |
|
|
|
--echo # |
|
|
|
--echo # Show that the original contents of t1 is intact: |
|
|
|
select * from t1; |
|
|
|
commit; |
|
|
|
--echo # |
|
|
|
--echo # Have a one more record in t2 to show that |
|
|
|
--echo # if join_read_key cache is purned, the current |
|
|
|
--echo # row under the cursor is unlocked (provided, this row didn't |
|
|
|
--echo # match the partial WHERE clause, of course). |
|
|
|
--echo # Sic: the result of this test dependent on the order of retrieval |
|
|
|
--echo # of records --echo # from the derived table, if ! |
|
|
|
--echo # We use DELETE to disable the JOIN CACHE. This DELETE modifies no |
|
|
|
--echo # records. It also should leave no InnoDB row locks. |
|
|
|
--echo # |
|
|
|
begin; |
|
|
|
delete t1.* from t1 natural join (select 2 as a, 2 as b union all |
|
|
|
select 0 as a, 0 as b) as t2; |
|
|
|
--echo # Demonstrate that nothing was deleted form t1 |
|
|
|
select * from t1; |
|
|
|
--echo # |
|
|
|
--echo # Switching to connection con1 |
|
|
|
connection con1; |
|
|
|
begin; |
|
|
|
--echo # Since there is another distinct record in the derived table |
|
|
|
--echo # the previous matching record in t1 -- (2,null) -- was unlocked. |
|
|
|
delete from t1; |
|
|
|
--echo # We will need the contents of the table again. |
|
|
|
rollback; |
|
|
|
select * from t1; |
|
|
|
commit; |
|
|
|
--echo # |
|
|
|
--echo # Switching to connection default |
|
|
|
connection default; |
|
|
|
rollback; |
|
|
|
begin; |
|
|
|
--echo # |
|
|
|
--echo # Before this patch, we could wrongly unlock a record |
|
|
|
--echo # that was cached and later used in a join. Demonstrate that |
|
|
|
--echo # this is no longer the case. |
|
|
|
--echo # Sic: this test is also order-dependent (i.e. the |
|
|
|
--echo # the bug would show up only if the first record in the union |
|
|
|
--echo # is retreived and processed first. |
|
|
|
--echo # |
|
|
|
--echo # Verify that JT_EQ_REF is used. |
|
|
|
--vertical_results |
|
|
|
explain |
|
|
|
select 1 from t1 natural join (select 3 as a, 2 as b union all |
|
|
|
select 3 as a, 1 as b) as t2 for update; |
|
|
|
--horizontal_results |
|
|
|
--echo # Lock the record. |
|
|
|
select 1 from t1 natural join (select 3 as a, 2 as b union all |
|
|
|
select 3 as a, 1 as b) as t2 for update; |
|
|
|
--echo # Switching to connection con1 |
|
|
|
connection con1; |
|
|
|
--echo # |
|
|
|
--echo # We should not be able to delete record (3,1) from t1, |
|
|
|
--echo # (previously it was possible). |
|
|
|
--echo # |
|
|
|
--error ER_LOCK_WAIT_TIMEOUT |
|
|
|
delete from t1 where a=3; |
|
|
|
--echo # Switching to connection default |
|
|
|
connection default; |
|
|
|
commit; |
|
|
|
|
|
|
|
disconnect con1; |
|
|
|
set @@session.tx_isolation=default; |
|
|
|
drop table t1; |
|
|
|
|
|
|
|
--echo # |
|
|
|
--echo # End of 5.1 tests |
|
|
|
--echo # |