summaryrefslogtreecommitdiff
path: root/mysql-test/include/concurrent.inc
blob: 66f8a65a1029d8ec0c749ccbaf2bd95f8cdca3a4 (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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# include/concurrent.inc
#
# Concurrent tests for transactional storage engines, mainly in UPDATE's
# Bug#3300
# Designed and tested by Sinisa Milivojevic, sinisa@mysql.com
#
# These variables have to be set before sourcing this script:
#   TRANSACTION ISOLATION LEVEL      REPEATABLE READ
#   innodb_locks_unsafe_for_binlog   0 (default) or 1 (by
#                                    --innodb_locks_unsafe_for_binlog)
#   $engine_type                     storage engine to be tested
#
# Last update:
# 2009-02-13 HH "Release_lock("hello")" is now also successful when delivering NULL,
#               replaced two sleeps by wait_condition. The last two "sleep 1" have not been
#               replaced as all tried wait conditions leaded to nondeterministic results, especially
#               to succeeding concurrent updates. To replace the sleeps there should be some time
#               planned (or internal knowledge of the server may help).
# 2006-08-02 ML test refactored
#               old name was t/innodb_concurrent.test
#               main code went into include/concurrent.inc
# 2008-06-03 KP test refactored; removed name locks, added comments.
#               renamed wrapper t/concurrent_innodb.test ->
#                           t/concurrent_innodb_unsafelog.test
#               new wrapper t/concurrent_innodb_safelog.test
#

--source include/not_embedded.inc

connection default;
#
# Show prerequisites for this test.
#
SELECT @@global.tx_isolation;
SELECT @@global.innodb_locks_unsafe_for_binlog;
#
# When innodb_locks_unsafe_for_binlog is not set (zero), which is the
# default, InnoDB takes "next-key locks"/"gap locks". This means it
# locks the gap before the keys that it accessed to find the rows to
# use for a statement. In this case we have to expect some more lock
# wait timeouts in the tests below as if innodb_locks_unsafe_for_binlog
# is set (non-zero). In the latter case no "next-key locks"/"gap locks"
# are taken and locks on keys that do not match the WHERE conditon are
# released. Hence less lock collisions occur.
# We use the variable $keep_locks to set the expectations for
# lock wait timeouts accordingly.
#
let $keep_locks= `SELECT NOT @@global.innodb_locks_unsafe_for_binlog`;
--echo # keep_locks == $keep_locks

#
# Set up privileges and remove user level locks, if exist.
#
GRANT USAGE ON test.* TO mysqltest@localhost;

#
# Preparatory cleanup.
#
--disable_warnings
drop table if exists t1;
--enable_warnings


--echo
--echo **
--echo ** two UPDATE's running and both changing distinct result sets
--echo **
  --echo ** connection thread1
  connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
  --echo ** Get user level lock (ULL) for thread 1
  select get_lock("hello",10);

      --echo ** connection thread2
      connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Start transaction for thread 2
      begin;
      --echo ** Update will cause a table scan and a new ULL  will
      --echo ** be created and blocked on the first row where tipo=11.
      send update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;

  --echo ** connection thread1
  connection thread1;
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
  --source include/wait_condition.inc
  --echo ** Start new transaction for thread 1
  begin;
  --echo ** Update on t1 will cause a table scan which will be blocked because
  --echo ** the previously initiated table scan applied exclusive key locks on 
  --echo ** all primary keys.
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
  --echo ** do not match the WHERE condition are released.
  if ($keep_locks)
  {
    --error ER_LOCK_WAIT_TIMEOUT
    update t1 set eta=2 where tipo=22;
  }
  if (!$keep_locks)
  {
    update t1 set eta=2 where tipo=22;
  }
  --echo ** Release user level name lock from thread 1. This will cause the ULL
  --echo ** on thread 2 to end its wait.
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
  DO release_lock("hello");
  --echo ** Table is now updated with a new eta on tipo=22 for thread 1.
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** Release the lock and collect result from update on thread 2
      reap;
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
      DO release_lock("hello");
      --echo ** Table should have eta updates where tipo=11 but updates made by
      --echo ** thread 1 shouldn't be visible yet.
      select * from t1;
      --echo ** Sending commit on thread 2.
      commit;

  --echo ** connection thread1
  connection thread1;
  --echo ** Make sure table reads didn't change yet on thread 1.
  select * from t1;
  --echo ** And send final commit on thread 1.
  commit;
  --echo ** Table should now be updated by both updates in the order of
  --echo ** thread 1,2.
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** Make sure the output is similar for t1.
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** two UPDATE's running and one changing result set
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
  --echo ** Get ULL "hello" on thread 1
  select get_lock("hello",10);

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Start transaction on thread 2
      begin;
      --echo ** Update will cause a table scan.
      --echo ** This will cause a hang on the first row where tipo=1 until the
      --echo ** blocking ULL is released.
      send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;

--echo ** connection thread1
  connection thread1;
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
  --source include/wait_condition.inc
  --echo ** Start transaction on thread 1
  begin;
  --echo ** Update on t1 will cause a table scan which will be blocked because
  --echo ** the previously initiated table scan applied exclusive key locks on 
  --echo ** all primary keys.
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
  --echo ** do not match the WHERE condition are released.
  if ($keep_locks)
  {
    --error ER_LOCK_WAIT_TIMEOUT
    update t1 set tipo=1 where tipo=2;
  }
  if (!$keep_locks)
  {
    update t1 set tipo=1 where tipo=2;
  }
  --echo ** Release ULL. This will release the next waiting ULL on thread 2.
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
  DO release_lock("hello");
  --echo ** The table should still be updated with updates for thread 1 only:
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** Release the lock and collect result from thread 2:
      reap;
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
      DO release_lock("hello");
      --echo ** Seen from thread 2 the table should have been updated on four
      --echo ** places.
      select * from t1;
      commit;

  --echo ** connection thread1
  connection thread1;
  --echo ** Thread 2 has committed but the result should remain the same for
  --echo ** thread 1 (updated on three places):
  select * from t1;
  commit;
  --echo ** After a commit the table should be merged with the previous 
  --echo ** commit.
  --echo ** This select should show both updates:
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** One UPDATE and one INSERT .... Monty's test
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1 (a int not null, b int not null);
  insert into t1 values (1,1),(2,1),(3,1),(4,1);
  --echo ** Create ULL 'hello2'
  select get_lock("hello2",10);

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Begin a new transaction on thread 2
      begin;
      --echo ** Update will create a table scan which creates a ULL where a=2;
      --echo ** this will hang waiting on thread 1.
      send update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;

  --echo ** connection thread1
  connection thread1;
  let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
  --source include/wait_condition.inc
  --echo ** Insert new values to t1 from thread 1; this created an implicit
  --echo ** commit since there are no on-going transactions.
  insert into t1 values (1,1);
  --echo ** Release the ULL (thread 2 updates will finish).
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
  DO release_lock("hello2");
  --echo ** ..but thread 1 will still see t1 as if nothing has happend:
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** Collect results from thread 2 and release the lock.
      reap;
# 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
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
      DO release_lock("hello2");
      --echo ** The table should look like the original+updates for thread 2,
      --echo ** and consist of new rows:
      select * from t1;
      --echo ** Commit changes from thread 2
      commit;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** one UPDATE changing result set and SELECT ... FOR UPDATE
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Begin a new transaction on thread 2
      begin;
      --echo ** Select a range for update.
      select * from t1 where tipo=2 FOR UPDATE;

  --echo ** connection thread1
  connection thread1;
  --echo ** Begin a new transaction on thread 1 
  begin;
  --echo ** Update the same range which is marked for update on thread 2; this
  --echo ** will hang because of row locks.
  --error ER_LOCK_WAIT_TIMEOUT
  update t1 set tipo=1 where tipo=2;
  --echo ** After the update the table will be unmodified because the previous
  --echo ** transaction failed and was rolled back.
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** The table should look unmodified from thread 2.
      select * from t1;
      --echo ** Sending a commit should release the row locks and enable
      --echo ** thread 1 to complete the transaction.
      commit;

  --echo ** connection thread1
  connection thread1;
  --echo ** Commit on thread 1.
  commit;

      --echo ** connection thread2
      connection thread2;
      --echo ** The table should not have been changed.
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  --echo ** Even on thread 1:
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** one UPDATE not changing result set and SELECT ... FOR UPDATE
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Starting new transaction on thread 2.
      begin;
      --echo ** Starting SELECT .. FOR UPDATE
      select * from t1 where tipo=2 FOR UPDATE;

  --echo ** connection thread1
  connection thread1;
  --echo 
  --echo ** Starting new transaction on thread 1
  begin;
  --echo ** Updating single row using a table scan. This will time out
  --echo ** because of ongoing transaction on thread 1 holding lock on
  --echo ** all primary keys in the scan.
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
  --echo ** do not match the WHERE condition are released.
  if ($keep_locks)
  {
    --error ER_LOCK_WAIT_TIMEOUT
    update t1 set tipo=11 where tipo=22;
  }
  if (!$keep_locks)
  {
    update t1 set tipo=11 where tipo=22;
  }
  --echo ** After the time out the transaction is aborted; no rows should
  --echo ** have changed.
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      --echo ** The same thing should hold true for the transaction on
      --echo ** thread 2
      select * from t1;
      send commit;

  --echo ** connection thread1
  connection thread1;
  commit;

      --echo ** connection thread2
      connection thread2;
      --echo ** Even after committing:
      reap;
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** two SELECT ... FOR UPDATE
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      --echo ** Begin a new transaction on thread 2
      begin;
      select * from t1 where tipo=2 FOR UPDATE;

  --echo ** connection thread1
  connection thread1;
  --echo ** Begin a new transaction on thread 1
  begin;
  --echo ** Selecting a range for update by table scan will be blocked
  --echo ** because of on-going transaction on thread 2.
  --error ER_LOCK_WAIT_TIMEOUT
  select * from t1 where tipo=1 FOR UPDATE;
  
      --echo ** connection thread2
      connection thread2;
      --echo ** Table will be unchanged and the select command will not be
      --echo ** blocked:
      select * from t1;
      --echo ** Commit transacton on thread 2.
      commit;

  --echo ** connection thread1
  connection thread1;
  --echo ** Commit transaction on thread 1.
  commit;

      --echo ** connection thread2
      connection thread2;
      --echo ** Make sure table isn't blocked on thread 2:
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  --echo ** Make sure table isn't blocked on thread 1:
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo
--echo **
--echo ** one UPDATE changing result set and DELETE
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      begin;
      send delete from t1 where tipo=2;
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
# succeding update in the following thread. Also the used status variables '%lock%' and
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
      sleep 1;

  --echo ** connection thread1
  connection thread1;
  begin;
  --error ER_LOCK_WAIT_TIMEOUT
  update t1 set tipo=1 where tipo=2;
  select * from t1;

      --echo ** connection thread2
      connection thread2;
      reap;
      select * from t1;
      send commit;

  --echo ** connection thread1
  connection thread1;
  commit;

      --echo ** connection thread2
      connection thread2;
      reap;
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  select * from t1;

--echo ** connection default
connection default;
drop table t1;


--echo 
--echo **
--echo ** one UPDATE not changing result set and DELETE
--echo **
  --echo ** connection thread1
  #connect (thread1, localhost, mysqltest,,);
  connection thread1;
  --echo ** Set up table
  eval SET SESSION STORAGE_ENGINE = $engine_type;
  create table t1(eta int(11) not null, tipo int(11), c varchar(255));
  insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
  insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
  insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
  insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
  insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
  insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
  insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
  insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
  insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");

      --echo ** connection thread2
      #connect (thread2, localhost, mysqltest,,);
      connection thread2;
      begin;
      send delete from t1 where tipo=2;
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
# succeding update in the following thread. Also the used status variables '%lock%' and
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
      sleep 1;
 
  --echo ** connection thread1
  connection thread1;
  begin;
  --echo ** Update on t1 will cause a table scan which will be blocked because
  --echo ** the previously initiated table scan applied exclusive key locks on 
  --echo ** all primary keys.
  --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
  --echo ** do not match the WHERE condition are released.
  if ($keep_locks)
  {
    --error ER_LOCK_WAIT_TIMEOUT
    update t1 set tipo=1 where tipo=22;
  }
  if (!$keep_locks)
  {
    update t1 set tipo=1 where tipo=22;
  }
  select * from t1;
    
      --echo ** connection thread2
      connection thread2;
      reap;
      select * from t1;
      send commit;

  --echo ** connection thread1
  connection thread1;
  commit;

      --echo ** connection thread2
      connection thread2;
      reap;
      select * from t1;

  --echo ** connection thread1
  connection thread1;
  select * from t1;

--echo ** Cleanup
connection thread1;
disconnect thread1;
--source include/wait_until_disconnected.inc
--echo ** connection thread2
connection thread2;
disconnect thread2;
--source include/wait_until_disconnected.inc
--echo ** connection default
connection default;
drop table t1;
drop user mysqltest@localhost;