~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to mysql-test/include/concurrent.inc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# include/concurrent.inc
 
2
#
 
3
# Concurrent tests for transactional storage engines, mainly in UPDATE's
 
4
# Bug#3300
 
5
# Designed and tested by Sinisa Milivojevic, sinisa@mysql.com
 
6
#
 
7
# These variables have to be set before sourcing this script:
 
8
#   TRANSACTION ISOLATION LEVEL      REPEATABLE READ
 
9
#   innodb_locks_unsafe_for_binlog   0 (default) or 1 (by
 
10
#                                    --innodb_locks_unsafe_for_binlog)
 
11
#   $engine_type                     storage engine to be tested
 
12
#
 
13
# Last update:
 
14
# 2009-02-13 HH "Release_lock("hello")" is now also successful when delivering NULL,
 
15
#               replaced two sleeps by wait_condition. The last two "sleep 1" have not been
 
16
#               replaced as all tried wait conditions leaded to nondeterministic results, especially
 
17
#               to succeeding concurrent updates. To replace the sleeps there should be some time
 
18
#               planned (or internal knowledge of the server may help).
 
19
# 2006-08-02 ML test refactored
 
20
#               old name was t/innodb_concurrent.test
 
21
#               main code went into include/concurrent.inc
 
22
# 2008-06-03 KP test refactored; removed name locks, added comments.
 
23
#               renamed wrapper t/concurrent_innodb.test ->
 
24
#                           t/concurrent_innodb_unsafelog.test
 
25
#               new wrapper t/concurrent_innodb_safelog.test
 
26
#
 
27
 
 
28
connection default;
 
29
#
 
30
# Show prerequisites for this test.
 
31
#
 
32
SELECT @@global.tx_isolation;
 
33
SELECT @@global.innodb_locks_unsafe_for_binlog;
 
34
#
 
35
# When innodb_locks_unsafe_for_binlog is not set (zero), which is the
 
36
# default, InnoDB takes "next-key locks"/"gap locks". This means it
 
37
# locks the gap before the keys that it accessed to find the rows to
 
38
# use for a statement. In this case we have to expect some more lock
 
39
# wait timeouts in the tests below as if innodb_locks_unsafe_for_binlog
 
40
# is set (non-zero). In the latter case no "next-key locks"/"gap locks"
 
41
# are taken and locks on keys that do not match the WHERE conditon are
 
42
# released. Hence less lock collisions occur.
 
43
# We use the variable $keep_locks to set the expectations for
 
44
# lock wait timeouts accordingly.
 
45
#
 
46
let $keep_locks= `SELECT NOT @@global.innodb_locks_unsafe_for_binlog`;
 
47
--echo # keep_locks == $keep_locks
 
48
 
 
49
#
 
50
# Set up privileges and remove user level locks, if exist.
 
51
#
 
52
GRANT USAGE ON test.* TO mysqltest@localhost;
 
53
 
 
54
#
 
55
# Preparatory cleanup.
 
56
#
 
57
--disable_warnings
 
58
drop table if exists t1;
 
59
--enable_warnings
 
60
 
 
61
 
 
62
--echo
 
63
--echo **
 
64
--echo ** two UPDATE's running and both changing distinct result sets
 
65
--echo **
 
66
  --echo ** connection thread1
 
67
  connect (thread1, localhost, mysqltest,,);
 
68
  connection thread1;
 
69
  --echo ** Set up table
 
70
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
71
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
72
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
73
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
74
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
75
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
76
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
77
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
78
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
79
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
80
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
81
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
82
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
83
  --echo ** Get user level lock (ULL) for thread 1
 
84
  select get_lock("hello",10);
 
85
 
 
86
      --echo ** connection thread2
 
87
      connect (thread2, localhost, mysqltest,,);
 
88
      connection thread2;
 
89
      --echo ** Start transaction for thread 2
 
90
      begin;
 
91
      --echo ** Update will cause a table scan and a new ULL  will
 
92
      --echo ** be created and blocked on the first row where tipo=11.
 
93
      send update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;
 
94
 
 
95
  --echo ** connection thread1
 
96
  connection thread1;
 
97
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
 
98
  --source include/wait_condition.inc
 
99
  --echo ** Start new transaction for thread 1
 
100
  begin;
 
101
  --echo ** Update on t1 will cause a table scan which will be blocked because
 
102
  --echo ** the previously initiated table scan applied exclusive key locks on 
 
103
  --echo ** all primary keys.
 
104
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
 
105
  --echo ** do not match the WHERE condition are released.
 
106
  if ($keep_locks)
 
107
  {
 
108
    --error ER_LOCK_WAIT_TIMEOUT
 
109
    update t1 set eta=2 where tipo=22;
 
110
  }
 
111
  if (!$keep_locks)
 
112
  {
 
113
    update t1 set eta=2 where tipo=22;
 
114
  }
 
115
  --echo ** Release user level name lock from thread 1. This will cause the ULL
 
116
  --echo ** on thread 2 to end its wait.
 
117
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
 
118
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
119
  DO release_lock("hello");
 
120
  --echo ** Table is now updated with a new eta on tipo=22 for thread 1.
 
121
  select * from t1;
 
122
 
 
123
      --echo ** connection thread2
 
124
      connection thread2;
 
125
      --echo ** Release the lock and collect result from update on thread 2
 
126
      reap;
 
127
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
 
128
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
129
      DO release_lock("hello");
 
130
      --echo ** Table should have eta updates where tipo=11 but updates made by
 
131
      --echo ** thread 1 shouldn't be visible yet.
 
132
      select * from t1;
 
133
      --echo ** Sending commit on thread 2.
 
134
      commit;
 
135
 
 
136
  --echo ** connection thread1
 
137
  connection thread1;
 
138
  --echo ** Make sure table reads didn't change yet on thread 1.
 
139
  select * from t1;
 
140
  --echo ** And send final commit on thread 1.
 
141
  commit;
 
142
  --echo ** Table should now be updated by both updates in the order of
 
143
  --echo ** thread 1,2.
 
144
  select * from t1;
 
145
 
 
146
      --echo ** connection thread2
 
147
      connection thread2;
 
148
      --echo ** Make sure the output is similar for t1.
 
149
      select * from t1;
 
150
 
 
151
  --echo ** connection thread1
 
152
  connection thread1;
 
153
  select * from t1;
 
154
 
 
155
--echo ** connection default
 
156
connection default;
 
157
drop table t1;
 
158
 
 
159
 
 
160
--echo
 
161
--echo **
 
162
--echo ** two UPDATE's running and one changing result set
 
163
--echo **
 
164
  --echo ** connection thread1
 
165
  #connect (thread1, localhost, mysqltest,,);
 
166
  connection thread1;
 
167
  --echo ** Set up table
 
168
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
169
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
170
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
171
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
172
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
173
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
174
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
175
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
176
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
177
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
178
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
179
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
180
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
181
  --echo ** Get ULL "hello" on thread 1
 
182
  select get_lock("hello",10);
 
183
 
 
184
      --echo ** connection thread2
 
185
      #connect (thread2, localhost, mysqltest,,);
 
186
      connection thread2;
 
187
      --echo ** Start transaction on thread 2
 
188
      begin;
 
189
      --echo ** Update will cause a table scan.
 
190
      --echo ** This will cause a hang on the first row where tipo=1 until the
 
191
      --echo ** blocking ULL is released.
 
192
      send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;
 
193
 
 
194
--echo ** connection thread1
 
195
  connection thread1;
 
196
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
 
197
  --source include/wait_condition.inc
 
198
  --echo ** Start transaction on thread 1
 
199
  begin;
 
200
  --echo ** Update on t1 will cause a table scan which will be blocked because
 
201
  --echo ** the previously initiated table scan applied exclusive key locks on 
 
202
  --echo ** all primary keys.
 
203
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
 
204
  --echo ** do not match the WHERE condition are released.
 
205
  if ($keep_locks)
 
206
  {
 
207
    --error ER_LOCK_WAIT_TIMEOUT
 
208
    update t1 set tipo=1 where tipo=2;
 
209
  }
 
210
  if (!$keep_locks)
 
211
  {
 
212
    update t1 set tipo=1 where tipo=2;
 
213
  }
 
214
  --echo ** Release ULL. This will release the next waiting ULL on thread 2.
 
215
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically)the success of the following
 
216
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
217
  DO release_lock("hello");
 
218
  --echo ** The table should still be updated with updates for thread 1 only:
 
219
  select * from t1;
 
220
 
 
221
      --echo ** connection thread2
 
222
      connection thread2;
 
223
      --echo ** Release the lock and collect result from thread 2:
 
224
      reap;
 
225
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
 
226
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
227
      DO release_lock("hello");
 
228
      --echo ** Seen from thread 2 the table should have been updated on four
 
229
      --echo ** places.
 
230
      select * from t1;
 
231
      commit;
 
232
 
 
233
  --echo ** connection thread1
 
234
  connection thread1;
 
235
  --echo ** Thread 2 has committed but the result should remain the same for
 
236
  --echo ** thread 1 (updated on three places):
 
237
  select * from t1;
 
238
  commit;
 
239
  --echo ** After a commit the table should be merged with the previous 
 
240
  --echo ** commit.
 
241
  --echo ** This select should show both updates:
 
242
  select * from t1;
 
243
 
 
244
      --echo ** connection thread2
 
245
      connection thread2;
 
246
      select * from t1;
 
247
 
 
248
  --echo ** connection thread1
 
249
  connection thread1;
 
250
  select * from t1;
 
251
 
 
252
--echo ** connection default
 
253
connection default;
 
254
drop table t1;
 
255
 
 
256
 
 
257
--echo
 
258
--echo **
 
259
--echo ** One UPDATE and one INSERT .... Monty's test
 
260
--echo **
 
261
  --echo ** connection thread1
 
262
  #connect (thread1, localhost, mysqltest,,);
 
263
  connection thread1;
 
264
  --echo ** Set up table
 
265
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
266
  create table t1 (a int not null, b int not null);
 
267
  insert into t1 values (1,1),(2,1),(3,1),(4,1);
 
268
  --echo ** Create ULL 'hello2'
 
269
  select get_lock("hello2",10);
 
270
 
 
271
      --echo ** connection thread2
 
272
      #connect (thread2, localhost, mysqltest,,);
 
273
      connection thread2;
 
274
      --echo ** Begin a new transaction on thread 2
 
275
      begin;
 
276
      --echo ** Update will create a table scan which creates a ULL where a=2;
 
277
      --echo ** this will hang waiting on thread 1.
 
278
      send update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;
 
279
 
 
280
  --echo ** connection thread1
 
281
  connection thread1;
 
282
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
 
283
  --source include/wait_condition.inc
 
284
  --echo ** Insert new values to t1 from thread 1; this created an implicit
 
285
  --echo ** commit since there are no on-going transactions.
 
286
  insert into t1 values (1,1);
 
287
  --echo ** Release the ULL (thread 2 updates will finish).
 
288
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
 
289
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
290
  DO release_lock("hello2");
 
291
  --echo ** ..but thread 1 will still see t1 as if nothing has happend:
 
292
  select * from t1;
 
293
 
 
294
      --echo ** connection thread2
 
295
      connection thread2;
 
296
      --echo ** Collect results from thread 2 and release the lock.
 
297
      reap;
 
298
# Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
 
299
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
 
300
      DO release_lock("hello2");
 
301
      --echo ** The table should look like the original+updates for thread 2,
 
302
      --echo ** and consist of new rows:
 
303
      select * from t1;
 
304
      --echo ** Commit changes from thread 2
 
305
      commit;
 
306
 
 
307
--echo ** connection default
 
308
connection default;
 
309
drop table t1;
 
310
 
 
311
 
 
312
--echo
 
313
--echo **
 
314
--echo ** one UPDATE changing result set and SELECT ... FOR UPDATE
 
315
--echo **
 
316
  --echo ** connection thread1
 
317
  #connect (thread1, localhost, mysqltest,,);
 
318
  connection thread1;
 
319
  --echo ** Set up table
 
320
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
321
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
322
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
323
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
324
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
325
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
326
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
327
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
328
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
329
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
330
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
331
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
332
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
333
 
 
334
      --echo ** connection thread2
 
335
      #connect (thread2, localhost, mysqltest,,);
 
336
      connection thread2;
 
337
      --echo ** Begin a new transaction on thread 2
 
338
      begin;
 
339
      --echo ** Select a range for update.
 
340
      select * from t1 where tipo=2 FOR UPDATE;
 
341
 
 
342
  --echo ** connection thread1
 
343
  connection thread1;
 
344
  --echo ** Begin a new transaction on thread 1 
 
345
  begin;
 
346
  --echo ** Update the same range which is marked for update on thread 2; this
 
347
  --echo ** will hang because of row locks.
 
348
  --error ER_LOCK_WAIT_TIMEOUT
 
349
  update t1 set tipo=1 where tipo=2;
 
350
  --echo ** After the update the table will be unmodified because the previous
 
351
  --echo ** transaction failed and was rolled back.
 
352
  select * from t1;
 
353
 
 
354
      --echo ** connection thread2
 
355
      connection thread2;
 
356
      --echo ** The table should look unmodified from thread 2.
 
357
      select * from t1;
 
358
      --echo ** Sending a commit should release the row locks and enable
 
359
      --echo ** thread 1 to complete the transaction.
 
360
      commit;
 
361
 
 
362
  --echo ** connection thread1
 
363
  connection thread1;
 
364
  --echo ** Commit on thread 1.
 
365
  commit;
 
366
 
 
367
      --echo ** connection thread2
 
368
      connection thread2;
 
369
      --echo ** The table should not have been changed.
 
370
      select * from t1;
 
371
 
 
372
  --echo ** connection thread1
 
373
  connection thread1;
 
374
  --echo ** Even on thread 1:
 
375
  select * from t1;
 
376
 
 
377
--echo ** connection default
 
378
connection default;
 
379
drop table t1;
 
380
 
 
381
 
 
382
--echo
 
383
--echo **
 
384
--echo ** one UPDATE not changing result set and SELECT ... FOR UPDATE
 
385
--echo **
 
386
  --echo ** connection thread1
 
387
  #connect (thread1, localhost, mysqltest,,);
 
388
  connection thread1;
 
389
  --echo ** Set up table
 
390
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
391
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
392
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
393
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
394
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
395
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
396
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
397
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
398
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
399
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
400
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
401
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
402
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
403
 
 
404
      --echo ** connection thread2
 
405
      #connect (thread2, localhost, mysqltest,,);
 
406
      connection thread2;
 
407
      --echo ** Starting new transaction on thread 2.
 
408
      begin;
 
409
      --echo ** Starting SELECT .. FOR UPDATE
 
410
      select * from t1 where tipo=2 FOR UPDATE;
 
411
 
 
412
  --echo ** connection thread1
 
413
  connection thread1;
 
414
  --echo 
 
415
  --echo ** Starting new transaction on thread 1
 
416
  begin;
 
417
  --echo ** Updating single row using a table scan. This will time out
 
418
  --echo ** because of ongoing transaction on thread 1 holding lock on
 
419
  --echo ** all primary keys in the scan.
 
420
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
 
421
  --echo ** do not match the WHERE condition are released.
 
422
  if ($keep_locks)
 
423
  {
 
424
    --error ER_LOCK_WAIT_TIMEOUT
 
425
    update t1 set tipo=11 where tipo=22;
 
426
  }
 
427
  if (!$keep_locks)
 
428
  {
 
429
    update t1 set tipo=11 where tipo=22;
 
430
  }
 
431
  --echo ** After the time out the transaction is aborted; no rows should
 
432
  --echo ** have changed.
 
433
  select * from t1;
 
434
 
 
435
      --echo ** connection thread2
 
436
      connection thread2;
 
437
      --echo ** The same thing should hold true for the transaction on
 
438
      --echo ** thread 2
 
439
      select * from t1;
 
440
      send commit;
 
441
 
 
442
  --echo ** connection thread1
 
443
  connection thread1;
 
444
  commit;
 
445
 
 
446
      --echo ** connection thread2
 
447
      connection thread2;
 
448
      --echo ** Even after committing:
 
449
      reap;
 
450
      select * from t1;
 
451
 
 
452
  --echo ** connection thread1
 
453
  connection thread1;
 
454
  select * from t1;
 
455
 
 
456
--echo ** connection default
 
457
connection default;
 
458
drop table t1;
 
459
 
 
460
 
 
461
--echo
 
462
--echo **
 
463
--echo ** two SELECT ... FOR UPDATE
 
464
--echo **
 
465
  --echo ** connection thread1
 
466
  #connect (thread1, localhost, mysqltest,,);
 
467
  connection thread1;
 
468
  --echo ** Set up table
 
469
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
470
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
471
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
472
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
473
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
474
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
475
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
476
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
477
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
478
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
479
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
480
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
481
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
482
 
 
483
      --echo ** connection thread2
 
484
      #connect (thread2, localhost, mysqltest,,);
 
485
      connection thread2;
 
486
      --echo ** Begin a new transaction on thread 2
 
487
      begin;
 
488
      select * from t1 where tipo=2 FOR UPDATE;
 
489
 
 
490
  --echo ** connection thread1
 
491
  connection thread1;
 
492
  --echo ** Begin a new transaction on thread 1
 
493
  begin;
 
494
  --echo ** Selecting a range for update by table scan will be blocked
 
495
  --echo ** because of on-going transaction on thread 2.
 
496
  --error ER_LOCK_WAIT_TIMEOUT
 
497
  select * from t1 where tipo=1 FOR UPDATE;
 
498
  
 
499
      --echo ** connection thread2
 
500
      connection thread2;
 
501
      --echo ** Table will be unchanged and the select command will not be
 
502
      --echo ** blocked:
 
503
      select * from t1;
 
504
      --echo ** Commit transacton on thread 2.
 
505
      commit;
 
506
 
 
507
  --echo ** connection thread1
 
508
  connection thread1;
 
509
  --echo ** Commit transaction on thread 1.
 
510
  commit;
 
511
 
 
512
      --echo ** connection thread2
 
513
      connection thread2;
 
514
      --echo ** Make sure table isn't blocked on thread 2:
 
515
      select * from t1;
 
516
 
 
517
  --echo ** connection thread1
 
518
  connection thread1;
 
519
  --echo ** Make sure table isn't blocked on thread 1:
 
520
  select * from t1;
 
521
 
 
522
--echo ** connection default
 
523
connection default;
 
524
drop table t1;
 
525
 
 
526
 
 
527
--echo
 
528
--echo **
 
529
--echo ** one UPDATE changing result set and DELETE
 
530
--echo **
 
531
  --echo ** connection thread1
 
532
  #connect (thread1, localhost, mysqltest,,);
 
533
  connection thread1;
 
534
  --echo ** Set up table
 
535
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
536
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
537
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
538
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
539
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
540
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
541
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
542
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
543
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
544
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
545
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
546
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
547
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
548
 
 
549
      --echo ** connection thread2
 
550
      #connect (thread2, localhost, mysqltest,,);
 
551
      connection thread2;
 
552
      begin;
 
553
      send delete from t1 where tipo=2;
 
554
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
 
555
# succeding update in the following thread. Also the used status variables '%lock%' and
 
556
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
 
557
      sleep 1;
 
558
 
 
559
  --echo ** connection thread1
 
560
  connection thread1;
 
561
  begin;
 
562
  --error ER_LOCK_WAIT_TIMEOUT
 
563
  update t1 set tipo=1 where tipo=2;
 
564
  select * from t1;
 
565
 
 
566
      --echo ** connection thread2
 
567
      connection thread2;
 
568
      reap;
 
569
      select * from t1;
 
570
      send commit;
 
571
 
 
572
  --echo ** connection thread1
 
573
  connection thread1;
 
574
  commit;
 
575
 
 
576
      --echo ** connection thread2
 
577
      connection thread2;
 
578
      reap;
 
579
      select * from t1;
 
580
 
 
581
  --echo ** connection thread1
 
582
  connection thread1;
 
583
  select * from t1;
 
584
 
 
585
--echo ** connection default
 
586
connection default;
 
587
drop table t1;
 
588
 
 
589
 
 
590
--echo 
 
591
--echo **
 
592
--echo ** one UPDATE not changing result set and DELETE
 
593
--echo **
 
594
  --echo ** connection thread1
 
595
  #connect (thread1, localhost, mysqltest,,);
 
596
  connection thread1;
 
597
  --echo ** Set up table
 
598
  eval SET SESSION STORAGE_ENGINE = $engine_type;
 
599
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
 
600
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
 
601
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 
602
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
 
603
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
 
604
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
 
605
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
 
606
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
 
607
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 
608
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
 
609
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
 
610
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
 
611
 
 
612
      --echo ** connection thread2
 
613
      #connect (thread2, localhost, mysqltest,,);
 
614
      connection thread2;
 
615
      begin;
 
616
      send delete from t1 where tipo=2;
 
617
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
 
618
# succeding update in the following thread. Also the used status variables '%lock%' and
 
619
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
 
620
      sleep 1;
 
621
 
 
622
  --echo ** connection thread1
 
623
  connection thread1;
 
624
  begin;
 
625
  --echo ** Update on t1 will cause a table scan which will be blocked because
 
626
  --echo ** the previously initiated table scan applied exclusive key locks on 
 
627
  --echo ** all primary keys.
 
628
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
 
629
  --echo ** do not match the WHERE condition are released.
 
630
  if ($keep_locks)
 
631
  {
 
632
    --error ER_LOCK_WAIT_TIMEOUT
 
633
    update t1 set tipo=1 where tipo=22;
 
634
  }
 
635
  if (!$keep_locks)
 
636
  {
 
637
    update t1 set tipo=1 where tipo=22;
 
638
  }
 
639
  select * from t1;
 
640
    
 
641
      --echo ** connection thread2
 
642
      connection thread2;
 
643
      reap;
 
644
      select * from t1;
 
645
      send commit;
 
646
 
 
647
  --echo ** connection thread1
 
648
  connection thread1;
 
649
  commit;
 
650
 
 
651
      --echo ** connection thread2
 
652
      connection thread2;
 
653
      reap;
 
654
      select * from t1;
 
655
 
 
656
  --echo ** connection thread1
 
657
  connection thread1;
 
658
  select * from t1;
 
659
 
 
660
--echo ** Cleanup
 
661
connection thread1;
 
662
disconnect thread1;
 
663
--source include/wait_until_disconnected.inc
 
664
--echo ** connection thread2
 
665
connection thread2;
 
666
disconnect thread2;
 
667
--source include/wait_until_disconnected.inc
 
668
--echo ** connection default
 
669
connection default;
 
670
drop table t1;
 
671
drop user mysqltest@localhost;
 
672