summaryrefslogtreecommitdiff
path: root/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test
blob: ea31d4a14c55353ca8316c84225d7c59518bd722 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
--source include/have_innodb.inc

--echo #
--echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout 
--echo #  without error
--echo #

CREATE TABLE t1 (a int, b int, PRIMARY KEY  (a,b)) ENGINE=InnoDB;

INSERT INTO t1 (a,b) VALUES (1070109,99);

CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB;

INSERT INTO t2 (b,a) VALUES (7,1070109);

SELECT * FROM t1;

BEGIN;

SELECT b FROM t2 WHERE b=7 FOR UPDATE;

CONNECT (addconroot, localhost, root,,);
CONNECTION addconroot;

BEGIN;

--error ER_LOCK_WAIT_TIMEOUT
SELECT b FROM t2 WHERE b=7 FOR UPDATE;

--error ER_LOCK_WAIT_TIMEOUT
INSERT IGNORE INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7));

--error ER_LOCK_WAIT_TIMEOUT
UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7);

--error ER_LOCK_WAIT_TIMEOUT
DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7);

SELECT * FROM t1;

CONNECTION default;
DISCONNECT addconroot;

DROP TABLE t2, t1;

--echo # End of 5.0 tests

--echo #
--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
--echo #           FOR UPDATE
--echo #
create table t1 (a int primary key auto_increment,
                 b int, index(b)) engine=innodb;
insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
set autocommit=0;
begin;
select * from t1 where b=5 for update;
connect (con1, localhost, root,,);
connection con1;
--error ER_LOCK_WAIT_TIMEOUT
insert ignore into t1 (b) select a as b from t1;
connection default;
--echo # Cleanup
--echo #
disconnect con1;
commit;
set autocommit=default;
drop table t1;

--echo #
--echo # Bug #37183 insert ignore into .. select ... hangs 
--echo #            after deadlock was encountered
--echo #
connect (con1,localhost,root,,);
create table t1(id int primary key,v int)engine=innodb;
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
create table t2 like t1;

--connection con1
begin;
update t1 set v=id*2 where id=1;

--connection default
begin;
update t1 set v=id*2 where id=2;

--connection con1
--error 1205
update t1 set v=id*2 where id=2;

--connection default
--error 1205
insert ignore into t2 select * from t1 where id=1; 
rollback;

--connection con1
rollback;

--connection default
disconnect con1;
drop table t1, t2;


--echo #
--echo # Bug#41756 Strange error messages about locks from InnoDB
--echo #
--echo # In the default transaction isolation mode,
--echo # handler::unlock_row() 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.
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
--replace_result "Using index condition; Using where" "Using where"
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,,);
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;
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;
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;
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
--replace_result "Using index condition; Using where" "Using where"
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;
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;
connection default;
commit;

disconnect con1;
set @@session.tx_isolation=default;
drop table t1;

--echo #
--echo # End of 5.1 tests
--echo #