1#
2# We need the Debug Sync Facility.
3#
4--source include/have_debug_sync.inc
5--source include/have_metadata_lock_info.inc
6
7# We need InnoDB tables for some of the tests.
8--source include/have_innodb.inc
9
10# Save the initial number of concurrent sessions.
11--source include/count_sessions.inc
12
13
14# Clean up resources used in this test case.
15--disable_warnings
16SET DEBUG_SYNC= 'RESET';
17--enable_warnings
18
19#
20# Test the case of when a exclusive lock request waits for a
21# shared lock being upgraded to a exclusive lock.
22#
23
24connect (con1,localhost,root,,test,,);
25connect (con2,localhost,root,,test,,);
26connect (con3,localhost,root,,test,,);
27
28connection default;
29
30--disable_warnings
31drop table if exists t1,t2,t3;
32--enable_warnings
33
34create table t1 (i int);
35create table t2 (i int);
36
37--echo connection: default
38lock tables t2 read;
39
40connection con1;
41--echo connection: con1
42set debug_sync='mdl_upgrade_lock SIGNAL parked WAIT_FOR go';
43--send alter table t1 rename t3
44
45connection default;
46--echo connection: default
47set debug_sync= 'now WAIT_FOR parked';
48
49connection con2;
50--echo connection: con2
51set debug_sync='mdl_acquire_lock_wait SIGNAL go';
52--send drop table t1,t2
53
54connection con1;
55--echo connection: con1
56--reap
57
58connection default;
59--echo connection: default
60unlock tables;
61
62connection con2;
63--echo connection: con2
64--error ER_BAD_TABLE_ERROR
65--reap
66
67connection default;
68drop table t3;
69
70disconnect con1;
71disconnect con2;
72disconnect con3;
73
74# Clean up resources used in this test case.
75--disable_warnings
76SET DEBUG_SYNC= 'RESET';
77--enable_warnings
78
79
80--echo #
81--echo # Basic test coverage for type-of-operation aware metadata locks.
82--echo #
83--disable_warnings
84drop table if exists t1, t2, t3;
85--enable_warnings
86connect(mdl_con1,localhost,root,,);
87connect(mdl_con2,localhost,root,,);
88connect(mdl_con3,localhost,root,,);
89connection default;
90set debug_sync= 'RESET';
91create table t1 (c1 int);
92
93--echo #
94--echo # A) First let us check compatibility rules between differend kinds of
95--echo #    type-of-operation aware metadata locks.
96--echo #    Of course, these rules are already covered by the tests scattered
97--echo #    across the test suite. But it still makes sense to have one place
98--echo #    which covers all of them.
99--echo #
100
101--echo # 1) Acquire S (simple shared) lock on the table (by using HANDLER):
102--echo #
103handler t1 open;
104--echo #
105connection mdl_con1;
106--echo # Check that S, SH, SR and SW locks are compatible with it.
107handler t1 open t;
108handler t close;
109select column_name from information_schema.columns where
110  table_schema='test' and table_name='t1';
111select count(*) from t1;
112insert into t1 values (1), (1);
113--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
114--echo # which will fail when constructing .frm and thus obtaining SU metadata
115--echo # lock.
116--error ER_KEY_COLUMN_DOES_NOT_EXITS
117alter table t1 add index (not_exist);
118--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
119--echo # which will fail during copying the table and thus obtaining SNW metadata
120--echo # lock.
121--error ER_DUP_ENTRY
122alter table t1 add primary key (c1);
123--echo # Check that X lock is incompatible with S lock.
124--echo # Sending:
125--send rename table t1 to t2;
126--echo #
127connection mdl_con2;
128--echo # Check that the above RENAME is blocked because of S lock.
129let $wait_condition=
130  select count(*) = 1 from information_schema.processlist
131  where state = "Waiting for table metadata lock" and
132        info = "rename table t1 to t2";
133--source include/wait_condition.inc
134--echo #
135connection default;
136--echo # Unblock RENAME TABLE.
137handler t1 close;
138--echo #
139connection mdl_con1;
140--echo # Reaping RENAME TABLE.
141--reap
142--echo # Restore the original state of the things.
143rename table t2 to t1;
144--echo #
145connection default;
146handler t1 open;
147--echo #
148connection mdl_con1;
149--echo # Check that upgrade from SNW to X is blocked by presence of S lock.
150--echo # Sending:
151--send alter table t1 add column c2 int;
152--echo #
153connection mdl_con2;
154--echo # Check that the above ALTER TABLE is blocked because of S lock.
155let $wait_condition=
156  select count(*) = 1 from information_schema.processlist
157  where state = "Waiting for table metadata lock" and
158        info = "alter table t1 add column c2 int";
159--source include/wait_condition.inc
160--echo #
161connection default;
162--echo # Unblock ALTER TABLE.
163handler t1 close;
164--echo #
165connection mdl_con1;
166--echo # Reaping ALTER TABLE.
167--reap
168--echo # Restore the original state of the things.
169alter table t1 drop column c2;
170--echo #
171connection default;
172--echo #
173--echo # 2) Acquire SH (shared high-priority) lock on the table.
174--echo #    We have to involve DEBUG_SYNC facility for this as usually
175--echo #    such kind of locks are short-lived.
176--echo #
177set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
178--echo # Sending:
179--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
180--echo #
181connection mdl_con1;
182set debug_sync= 'now WAIT_FOR locked';
183--echo # Check that S, SH, SR and SW locks are compatible with it.
184handler t1 open;
185handler t1 close;
186select column_name from information_schema.columns where
187  table_schema='test' and table_name='t1';
188select count(*) from t1;
189insert into t1 values (1);
190--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
191--echo # which will fail when constructing .frm and thus obtaining SU metadata
192--echo # lock.
193--error ER_KEY_COLUMN_DOES_NOT_EXITS
194alter table t1 add index (not_exist);
195--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
196--echo # which will fail during copying the table and thus obtaining SNW metadata
197--echo # lock.
198--error ER_DUP_ENTRY
199alter table t1 add primary key (c1);
200--echo # Check that SNRW lock is compatible with SH lock.
201lock table t1 write;
202delete from t1 limit 1;
203unlock tables;
204--echo # Check that X lock is incompatible with SH lock.
205--echo # Sending:
206--send rename table t1 to t2;
207--echo #
208connection mdl_con2;
209--echo # Check that the above RENAME is blocked because of SH lock.
210let $wait_condition=
211  select count(*) = 1 from information_schema.processlist
212  where state = "Waiting for table metadata lock" and
213        info = "rename table t1 to t2";
214--source include/wait_condition.inc
215--echo # Unblock RENAME TABLE.
216set debug_sync= 'now SIGNAL finish';
217--echo #
218connection default;
219--echo # Reaping SELECT ... FROM I_S.
220--reap
221--echo #
222connection mdl_con1;
223--echo # Reaping RENAME TABLE.
224--reap
225--echo # Restore the original state of the things.
226rename table t2 to t1;
227--echo #
228connection default;
229set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
230--echo # Sending:
231--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
232--echo #
233connection mdl_con1;
234set debug_sync= 'now WAIT_FOR locked';
235--echo # Check that upgrade from SNW to X is blocked by presence of SH lock.
236--echo # Sending:
237--send alter table t1 add column c2 int;
238--echo #
239connection mdl_con2;
240--echo # Check that the above ALTER TABLE is blocked because of SH lock.
241let $wait_condition=
242  select count(*) = 1 from information_schema.processlist
243  where state = "Waiting for table metadata lock" and
244        info = "alter table t1 add column c2 int";
245--source include/wait_condition.inc
246--echo # Unblock RENAME TABLE.
247set debug_sync= 'now SIGNAL finish';
248--echo #
249connection default;
250--echo # Reaping SELECT ... FROM I_S.
251--reap
252--echo #
253connection mdl_con1;
254--echo # Reaping ALTER TABLE.
255--reap
256--echo # Restore the original state of the things.
257alter table t1 drop column c2;
258--echo #
259connection default;
260set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
261--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
262--echo #
263connection mdl_con1;
264set debug_sync= 'now WAIT_FOR locked';
265--echo # Check that upgrade from SNRW to X is blocked by presence of S lock.
266lock table t1 write;
267--echo # Sending:
268--send alter table t1 add column c2 int;
269--echo #
270connection mdl_con2;
271--echo # Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
272--echo # because of S lock.
273let $wait_condition=
274  select count(*) = 1 from information_schema.processlist
275  where state = "Waiting for table metadata lock" and
276        info = "alter table t1 add column c2 int";
277--source include/wait_condition.inc
278--echo # Unblock RENAME TABLE.
279set debug_sync= 'now SIGNAL finish';
280--echo #
281connection default;
282--echo # Reaping SELECT ... FROM I_S.
283--reap
284--echo #
285connection mdl_con1;
286--echo # Reaping ALTER TABLE.
287--reap
288--echo # Restore the original state of the things.
289alter table t1 drop column c2;
290unlock tables;
291--echo #
292connection default;
293--echo #
294--echo #
295--echo # 3) Acquire SR lock on the table.
296--echo #
297--echo #
298begin;
299select count(*) from t1;
300--echo #
301connection mdl_con1;
302--echo # Check that S, SH, SR and SW locks are compatible with it.
303handler t1 open;
304handler t1 close;
305select column_name from information_schema.columns where
306  table_schema='test' and table_name='t1';
307select count(*) from t1;
308insert into t1 values (1);
309--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
310--echo # which will fail when constructing .frm and thus obtaining SU metadata
311--echo # lock.
312--error ER_KEY_COLUMN_DOES_NOT_EXITS
313alter table t1 add index (not_exist);
314--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
315--echo # which will fail during copying the table and thus obtaining SNW metadata
316--echo # lock.
317--error ER_DUP_ENTRY
318alter table t1 add primary key (c1);
319--echo # Check that SNRW lock is not compatible with SR lock.
320--echo # Sending:
321--send lock table t1 write;
322--echo #
323connection default;
324--echo # Check that the above LOCK TABLES is blocked because of SR lock.
325let $wait_condition=
326  select count(*) = 1 from information_schema.processlist
327  where state = "Waiting for table metadata lock" and
328        info = "lock table t1 write";
329--source include/wait_condition.inc
330--echo # Unblock LOCK TABLES.
331commit;
332--echo #
333connection mdl_con1;
334--echo # Reaping LOCK TABLES.
335--reap
336delete from t1 limit 1;
337unlock tables;
338--echo #
339connection default;
340begin;
341select count(*) from t1;
342--echo #
343connection mdl_con1;
344--echo # Check that X lock is incompatible with SR lock.
345--echo # Sending:
346--send rename table t1 to t2;
347--echo #
348connection mdl_con2;
349--echo # Check that the above RENAME is blocked because of SR lock.
350let $wait_condition=
351  select count(*) = 1 from information_schema.processlist
352  where state = "Waiting for table metadata lock" and
353        info = "rename table t1 to t2";
354--source include/wait_condition.inc
355--echo #
356connection default;
357--echo # Unblock RENAME TABLE.
358commit;
359--echo #
360connection mdl_con1;
361--echo # Reaping RENAME TABLE.
362--reap
363--echo # Restore the original state of the things.
364rename table t2 to t1;
365--echo #
366connection default;
367begin;
368select count(*) from t1;
369--echo #
370connection mdl_con1;
371--echo # Check that upgrade from SNW to X is blocked by presence of SR lock.
372--echo # Sending:
373--send alter table t1 add column c2 int;
374--echo #
375connection mdl_con2;
376--echo # Check that the above ALTER TABLE is blocked because of SR lock.
377let $wait_condition=
378  select count(*) = 1 from information_schema.processlist
379  where state = "Waiting for table metadata lock" and
380        info = "alter table t1 add column c2 int";
381--source include/wait_condition.inc
382--echo #
383connection default;
384--echo # Unblock ALTER TABLE.
385commit;
386--echo #
387connection mdl_con1;
388--echo # Reaping ALTER TABLE.
389--reap
390--echo # Restore the original state of the things.
391alter table t1 drop column c2;
392--echo #
393--echo # There is no need to check that upgrade from SNRW to X is blocked
394--echo # by presence of SR lock because SNRW is incompatible with SR anyway.
395--echo #
396--echo #
397connection default;
398--echo #
399--echo #
400--echo # 4) Acquire SW lock on the table.
401--echo #
402--echo #
403begin;
404insert into t1 values (1);
405--echo #
406connection mdl_con1;
407--echo # Check that S, SH, SR and SW locks are compatible with it.
408handler t1 open;
409handler t1 close;
410select column_name from information_schema.columns where
411  table_schema='test' and table_name='t1';
412--echo # Disable result log to make test robust against
413--echo # effects of concurrent insert.
414--disable_result_log
415select * from t1;
416--enable_result_log
417insert into t1 values (1);
418--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
419--echo # which will fail when constructing .frm and thus obtaining SU metadata
420--echo # lock.
421--error ER_KEY_COLUMN_DOES_NOT_EXITS
422alter table t1 add index (not_exist);
423--echo # Check that SNW lock is not compatible with SW lock.
424--echo # Again we use ALTER TABLE which fails during copying
425--echo # the table to avoid upgrade of SNW -> X.
426--echo # Sending:
427--send alter table t1 add primary key (c1);
428--echo #
429connection default;
430--echo # Check that the above ALTER TABLE is blocked because of SW lock.
431let $wait_condition=
432  select count(*) = 1 from information_schema.processlist
433  where state = "Waiting for table metadata lock" and
434        info = "alter table t1 add primary key (c1)";
435--source include/wait_condition.inc
436--echo # Unblock ALTER TABLE.
437commit;
438--echo #
439connection mdl_con1;
440--echo # Reaping ALTER TABLE.
441--error ER_DUP_ENTRY
442--reap
443--echo #
444connection default;
445begin;
446insert into t1 values (1);
447--echo #
448connection mdl_con1;
449--echo # Check that SNRW lock is not compatible with SW lock.
450--echo # Sending:
451--send lock table t1 write;
452--echo #
453connection default;
454--echo # Check that the above LOCK TABLES is blocked because of SW lock.
455let $wait_condition=
456  select count(*) = 1 from information_schema.processlist
457  where state = "Waiting for table metadata lock" and
458        info = "lock table t1 write";
459--source include/wait_condition.inc
460--echo # Unblock LOCK TABLES.
461commit;
462--echo #
463connection mdl_con1;
464--echo # Reaping LOCK TABLES.
465--reap
466delete from t1 limit 2;
467unlock tables;
468--echo #
469connection default;
470begin;
471insert into t1 values (1);
472--echo #
473connection mdl_con1;
474--echo # Check that X lock is incompatible with SW lock.
475--echo # Sending:
476--send rename table t1 to t2;
477--echo #
478connection mdl_con2;
479--echo # Check that the above RENAME is blocked because of SW lock.
480let $wait_condition=
481  select count(*) = 1 from information_schema.processlist
482  where state = "Waiting for table metadata lock" and
483        info = "rename table t1 to t2";
484--source include/wait_condition.inc
485--echo #
486connection default;
487--echo # Unblock RENAME TABLE.
488commit;
489--echo #
490connection mdl_con1;
491--echo # Reaping RENAME TABLE.
492--reap
493--echo # Restore the original state of the things.
494rename table t2 to t1;
495--echo #
496--echo # There is no need to check that upgrade from SNW/SNRW to X is
497--echo # blocked by presence of SW lock because SNW/SNRW is incompatible
498--echo # with SW anyway.
499--echo #
500--echo #
501connection default;
502--echo #
503--echo #
504--echo # 5) Acquire SU lock on the table. We have to use DEBUG_SYNC for
505--echo #    this, to prevent SU from being immediately upgraded to X.
506--echo #
507set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
508--echo # Sending:
509--send alter table t1 add primary key (c1);
510--echo #
511connection mdl_con1;
512set debug_sync= 'now WAIT_FOR locked';
513--echo # Check that S, SH, SR and SW locks are compatible with it.
514handler t1 open;
515handler t1 close;
516select column_name from information_schema.columns where
517  table_schema='test' and table_name='t1';
518select count(*) from t1;
519delete from t1 limit 1;
520--echo # Check that SU lock is incompatible with SU lock.
521--echo # Sending:
522--send alter table t1 add primary key (c1);
523--echo #
524connection mdl_con2;
525--echo # Check that the above ALTER is blocked because of SU lock.
526let $wait_condition=
527  select count(*) = 1 from information_schema.processlist
528  where state = "Waiting for table metadata lock" and
529        info = "alter table t1 add primary key (c1)";
530--source include/wait_condition.inc
531--echo # Unblock ALTERs.
532set debug_sync= 'now SIGNAL finish';
533--echo #
534connection default;
535--echo # Reaping first ALTER TABLE.
536--error ER_DUP_ENTRY
537--reap
538--echo #
539connection mdl_con1;
540--echo # Reaping another ALTER TABLE.
541--error ER_DUP_ENTRY
542--reap
543--echo #
544connection default;
545set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
546--echo # Sending:
547--send alter table t1 add primary key (c1);
548--echo #
549connection mdl_con1;
550set debug_sync= 'now WAIT_FOR locked';
551--echo # Check that SNRW lock is incompatible with SU lock.
552--echo # Sending:
553--send lock table t1 write;
554--echo #
555connection mdl_con2;
556--echo # Check that the above LOCK TABLES is blocked because of SU lock.
557let $wait_condition=
558  select count(*) = 1 from information_schema.processlist
559  where state = "Waiting for table metadata lock" and
560        info = "lock table t1 write";
561--source include/wait_condition.inc
562--echo # Unblock ALTER and thus LOCK TABLES.
563set debug_sync= 'now SIGNAL finish';
564--echo #
565connection default;
566--echo # Reaping ALTER TABLE.
567--error ER_DUP_ENTRY
568--reap
569--echo #
570connection mdl_con1;
571--echo # Reaping LOCK TABLES
572--reap
573insert into t1 values (1);
574unlock tables;
575--echo #
576connection default;
577set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
578--echo # Sending:
579--send alter table t1 add primary key (c1);
580--echo #
581connection mdl_con1;
582set debug_sync= 'now WAIT_FOR locked';
583--echo # Check that X lock is incompatible with SU lock.
584--echo # Sending:
585--send rename table t1 to t2;
586--echo #
587connection mdl_con2;
588--echo # Check that the above RENAME is blocked because of SU lock.
589let $wait_condition=
590  select count(*) = 1 from information_schema.processlist
591  where state = "Waiting for table metadata lock" and
592        info = "rename table t1 to t2";
593--source include/wait_condition.inc
594--echo # Unblock ALTER and thus RENAME TABLE.
595set debug_sync= 'now SIGNAL finish';
596--echo #
597connection default;
598--echo # Now we have ALTER TABLE with SU->SNW and RENAME TABLE with pending
599--echo # X-lock. In this case ALTER TABLE should be chosen as victim.
600--echo # Reaping ALTER TABLE.
601--error ER_LOCK_DEADLOCK
602--reap
603--echo #
604connection mdl_con1;
605--echo # Reaping RENAME TABLE
606--reap
607--echo # Revert back to original state of things.
608rename table t2 to t1;
609--echo #
610--echo # There is no need to check that upgrade from SNW/SNRW to X is
611--echo # blocked by presence of another SU lock because SNW/SNRW is
612--echo # incompatible with SU anyway.
613--echo #
614connection default;
615--echo #
616--echo #
617--echo # 6) Acquire SNW lock on the table. We have to use DEBUG_SYNC for
618--echo #    this, to prevent SNW from being immediately upgraded to X.
619--echo #
620set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
621--echo # Sending:
622--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
623--echo #
624connection mdl_con1;
625set debug_sync= 'now WAIT_FOR locked';
626--echo # Check that S, SH and SR locks are compatible with it.
627handler t1 open;
628handler t1 close;
629select column_name from information_schema.columns where
630  table_schema='test' and table_name='t1';
631select count(*) from t1;
632--echo # Check that SW lock is incompatible with SNW lock.
633--echo # Sending:
634--send delete from t1 limit 2;
635--echo #
636connection mdl_con2;
637--echo # Check that the above DELETE is blocked because of SNW lock.
638let $wait_condition=
639  select count(*) = 1 from information_schema.processlist
640  where state = "Waiting for table metadata lock" and
641        info = "delete from t1 limit 2";
642--source include/wait_condition.inc
643--echo # Unblock ALTER and thus DELETE.
644set debug_sync= 'now SIGNAL finish';
645--echo #
646connection default;
647--echo # Reaping ALTER TABLE.
648--error ER_DUP_ENTRY
649--reap
650--echo #
651connection mdl_con1;
652--echo # Reaping DELETE.
653--reap
654--echo #
655connection default;
656set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
657--echo # Sending:
658--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
659--echo #
660connection mdl_con1;
661set debug_sync= 'now WAIT_FOR locked';
662--echo # Check that SU lock is incompatible with SNW lock.
663--echo # Sending:
664--send alter table t1 add primary key (c1);
665--echo #
666connection mdl_con2;
667--echo # Check that the above ALTER is blocked because of SNW lock.
668let $wait_condition=
669  select count(*) = 1 from information_schema.processlist
670  where state = "Waiting for table metadata lock" and
671        info = "alter table t1 add primary key (c1)";
672--source include/wait_condition.inc
673--echo # Unblock ALTERs.
674set debug_sync= 'now SIGNAL finish';
675--echo #
676connection default;
677--echo # Reaping first ALTER TABLE.
678--error ER_DUP_ENTRY
679--reap
680--echo #
681connection mdl_con1;
682--echo # Reaping another ALTER TABLE.
683--error ER_DUP_ENTRY
684--reap
685--echo #
686--echo # Note that we can't easily check SNW vs SNW locks since
687--echo # SNW is only used by ALTER TABLE after upgrading from SU
688--echo # and SU is also incompatible with SNW.
689--echo #
690connection default;
691set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
692--echo # Sending:
693--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
694--echo #
695connection mdl_con1;
696set debug_sync= 'now WAIT_FOR locked';
697--echo # Check that SNRW lock is incompatible with SNW lock.
698--echo # Sending:
699--send lock table t1 write;
700--echo #
701connection mdl_con2;
702--echo # Check that the above LOCK TABLES is blocked because of SNW lock.
703let $wait_condition=
704  select count(*) = 1 from information_schema.processlist
705  where state = "Waiting for table metadata lock" and
706        info = "lock table t1 write";
707--source include/wait_condition.inc
708--echo # Unblock ALTER and thus LOCK TABLES.
709set debug_sync= 'now SIGNAL finish';
710--echo #
711connection default;
712--echo # Reaping ALTER TABLE.
713--error ER_DUP_ENTRY
714--reap
715--echo #
716connection mdl_con1;
717--echo # Reaping LOCK TABLES
718--reap
719insert into t1 values (1);
720unlock tables;
721--echo #
722connection default;
723set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
724--echo # Sending:
725--send alter table t1 add primary key (c1), algorithm=copy, lock=shared;
726--echo #
727connection mdl_con1;
728set debug_sync= 'now WAIT_FOR locked';
729--echo # Check that X lock is incompatible with SNW lock.
730--echo # Sending:
731--send rename table t1 to t2;
732--echo #
733connection mdl_con2;
734--echo # Check that the above RENAME is blocked because of SNW lock.
735let $wait_condition=
736  select count(*) = 1 from information_schema.processlist
737  where state = "Waiting for table metadata lock" and
738        info = "rename table t1 to t2";
739--source include/wait_condition.inc
740--echo # Unblock ALTER and thus RENAME TABLE.
741set debug_sync= 'now SIGNAL finish';
742--echo #
743connection default;
744--echo # Reaping ALTER TABLE.
745--error ER_DUP_ENTRY
746--reap
747--echo #
748connection mdl_con1;
749--echo # Reaping RENAME TABLE
750--reap
751--echo # Revert back to original state of things.
752rename table t2 to t1;
753--echo #
754--echo # There is no need to check that upgrade from SNW/SNRW to X is
755--echo # blocked by presence of another SNW lock because SNW/SNRW is
756--echo # incompatible with SNW anyway.
757--echo #
758connection default;
759--echo #
760--echo #
761--echo # 7) Acquire SNRW lock on the table.
762--echo #
763--echo #
764lock table t1 write;
765--echo #
766connection mdl_con1;
767--echo # Check that S and SH locks are compatible with it.
768select column_name from information_schema.columns where
769  table_schema='test' and table_name='t1';
770--echo # Check that SR lock is incompatible with SNRW lock.
771--echo # Sending:
772--send select count(*) from t1;
773--echo #
774connection default;
775--echo # Check that the above SELECT is blocked because of SNRW lock.
776let $wait_condition=
777  select count(*) = 1 from information_schema.processlist
778  where state = "Waiting for table metadata lock" and
779        info = "select count(*) from t1";
780--source include/wait_condition.inc
781--echo # Unblock SELECT.
782unlock tables;
783--echo #
784connection mdl_con1;
785--echo # Reaping SELECT.
786--reap
787--echo #
788connection default;
789lock table t1 write;
790--echo #
791connection mdl_con1;
792--echo # Check that SW lock is incompatible with SNRW lock.
793--echo # Sending:
794--send delete from t1 limit 1;
795--echo #
796connection default;
797--echo # Check that the above DELETE is blocked because of SNRW lock.
798let $wait_condition=
799  select count(*) = 1 from information_schema.processlist
800  where state = "Waiting for table metadata lock" and
801        info = "delete from t1 limit 1";
802--source include/wait_condition.inc
803--echo # Unblock DELETE.
804unlock tables;
805--echo #
806connection mdl_con1;
807--echo # Reaping DELETE.
808--reap
809--echo #
810connection default;
811lock table t1 write;
812--echo #
813connection mdl_con1;
814--echo # Check that SU lock is incompatible with SNRW lock.
815--echo # Sending:
816--send alter table t1 add primary key (c1);
817--echo #
818connection default;
819--echo # Check that the above ALTER is blocked because of SNRW lock.
820let $wait_condition=
821  select count(*) = 1 from information_schema.processlist
822  where state = "Waiting for table metadata lock" and
823        info = "alter table t1 add primary key (c1)";
824--source include/wait_condition.inc
825--echo # Unblock ALTER.
826unlock tables;
827--echo #
828connection mdl_con1;
829--echo # Reaping ALTER TABLE.
830--error ER_DUP_ENTRY
831--reap
832--echo #
833--echo # Note that we can't easily check SNW vs SNRW locks since
834--echo # SNW is only used by ALTER TABLE after upgrading from SU
835--echo # and SU is also incompatible with SNRW.
836--echo #
837connection default;
838lock table t1 write;
839--echo #
840connection mdl_con1;
841--echo # Check that SNRW lock is incompatible with SNRW lock.
842--echo # Sending:
843--send lock table t1 write;
844--echo #
845connection default;
846--echo # Check that the above LOCK TABLES is blocked because of SNRW lock.
847let $wait_condition=
848  select count(*) = 1 from information_schema.processlist
849  where state = "Waiting for table metadata lock" and
850        info = "lock table t1 write";
851--source include/wait_condition.inc
852--echo # Unblock waiting LOCK TABLES.
853unlock tables;
854--echo #
855connection mdl_con1;
856--echo # Reaping LOCK TABLES
857--reap
858insert into t1 values (1);
859unlock tables;
860--echo #
861connection default;
862lock table t1 write;
863--echo #
864connection mdl_con1;
865--echo # Check that X lock is incompatible with SNRW lock.
866--echo # Sending:
867--send rename table t1 to t2;
868--echo #
869connection default;
870--echo # Check that the above RENAME is blocked because of SNRW lock.
871let $wait_condition=
872  select count(*) = 1 from information_schema.processlist
873  where state = "Waiting for table metadata lock" and
874        info = "rename table t1 to t2";
875--source include/wait_condition.inc
876--echo # Unblock RENAME TABLE
877unlock tables;
878--echo #
879connection mdl_con1;
880--echo # Reaping RENAME TABLE
881--reap
882--echo # Revert back to original state of things.
883rename table t2 to t1;
884--echo #
885--echo # There is no need to check that upgrade from SNW/SNRW to X is
886--echo # blocked by presence of another SNRW lock because SNW/SNRW is
887--echo # incompatible with SNRW anyway.
888--echo #
889connection default;
890--echo #
891--echo #
892--echo # 8) Now do the same round of tests for X lock. We use additional
893--echo #    table to get long-lived lock of this type.
894--echo #
895create table t2 (c1 int);
896--echo #
897connection mdl_con2;
898--echo # Take a lock on t2, so RENAME TABLE t1 TO t2 will get blocked
899--echo # after acquiring X lock on t1.
900lock tables t2 read;
901--echo #
902connection default;
903--echo # Sending:
904--send rename table t1 to t2;
905--echo #
906connection mdl_con1;
907--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
908let $wait_condition=
909select count(*) = 1 from information_schema.processlist
910where state = "Waiting for table metadata lock" and
911      info = "rename table t1 to t2";
912--source include/wait_condition.inc
913--echo # Check that S lock in incompatible with X lock.
914--echo # Sending:
915--send handler t1 open;
916--echo #
917connection mdl_con2;
918--echo # Check that the above HANDLER statement is blocked because of X lock.
919let $wait_condition=
920select count(*) = 1 from information_schema.processlist
921where state = "Waiting for table metadata lock" and
922      info = "handler t1 open";
923--source include/wait_condition.inc
924--echo # Unblock RENAME TABLE
925unlock tables;
926--echo #
927connection default;
928--echo # Reaping RENAME TABLE.
929--error ER_TABLE_EXISTS_ERROR
930--reap
931--echo #
932connection mdl_con1;
933--echo # Reaping HANDLER.
934--reap
935handler t1 close;
936--echo #
937connection mdl_con2;
938--echo # Prepare for blocking RENAME TABLE.
939lock tables t2 read;
940--echo #
941connection default;
942--echo # Sending:
943--send rename table t1 to t2;
944--echo #
945connection mdl_con1;
946--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
947let $wait_condition=
948select count(*) = 1 from information_schema.processlist
949where state = "Waiting for table metadata lock" and
950      info = "rename table t1 to t2";
951--source include/wait_condition.inc
952--echo # Check that SH lock in incompatible with X lock.
953--echo # Sending:
954--send select column_name from information_schema.columns where table_schema='test' and table_name='t1';
955--echo #
956connection mdl_con2;
957--echo # Check that the above SELECT ... FROM I_S ... statement is blocked
958--echo # because of X lock.
959let $wait_condition=
960select count(*) = 1 from information_schema.processlist
961where state = "Waiting for table metadata lock" and
962      info like "select column_name from information_schema.columns%";
963--source include/wait_condition.inc
964--echo # Unblock RENAME TABLE
965unlock tables;
966--echo #
967connection default;
968--echo # Reaping RENAME TABLE.
969--error ER_TABLE_EXISTS_ERROR
970--reap
971--echo #
972connection mdl_con1;
973--echo # Reaping SELECT ... FROM I_S.
974--reap
975--echo #
976connection mdl_con2;
977--echo # Prepare for blocking RENAME TABLE.
978lock tables t2 read;
979--echo #
980connection default;
981--echo # Sending:
982--send rename table t1 to t2;
983--echo #
984connection mdl_con1;
985--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
986let $wait_condition=
987select count(*) = 1 from information_schema.processlist
988where state = "Waiting for table metadata lock" and
989      info = "rename table t1 to t2";
990--source include/wait_condition.inc
991--echo # Check that SR lock in incompatible with X lock.
992--echo # Sending:
993--send select count(*) from t1;
994--echo #
995connection mdl_con2;
996--echo # Check that the above SELECT statement is blocked
997--echo # because of X lock.
998let $wait_condition=
999select count(*) = 1 from information_schema.processlist
1000where state = "Waiting for table metadata lock" and
1001      info = "select count(*) from t1";
1002--source include/wait_condition.inc
1003--echo # Unblock RENAME TABLE
1004unlock tables;
1005--echo #
1006connection default;
1007--echo # Reaping RENAME TABLE.
1008--error ER_TABLE_EXISTS_ERROR
1009--reap
1010--echo #
1011connection mdl_con1;
1012--echo # Reaping SELECT.
1013--reap
1014--echo #
1015connection mdl_con2;
1016--echo # Prepare for blocking RENAME TABLE.
1017lock tables t2 read;
1018--echo #
1019connection default;
1020--echo # Sending:
1021--send rename table t1 to t2;
1022--echo #
1023connection mdl_con1;
1024--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
1025let $wait_condition=
1026select count(*) = 1 from information_schema.processlist
1027where state = "Waiting for table metadata lock" and
1028      info = "rename table t1 to t2";
1029--source include/wait_condition.inc
1030--echo # Check that SW lock in incompatible with X lock.
1031--echo # Sending:
1032--send delete from t1 limit 1;
1033--echo #
1034connection mdl_con2;
1035--echo # Check that the above DELETE statement is blocked
1036--echo # because of X lock.
1037let $wait_condition=
1038select count(*) = 1 from information_schema.processlist
1039where state = "Waiting for table metadata lock" and
1040      info = "delete from t1 limit 1";
1041--source include/wait_condition.inc
1042--echo # Unblock RENAME TABLE
1043unlock tables;
1044--echo #
1045connection default;
1046--echo # Reaping RENAME TABLE.
1047--error ER_TABLE_EXISTS_ERROR
1048--reap
1049--echo #
1050connection mdl_con1;
1051--echo # Reaping DELETE.
1052--reap
1053--echo #
1054connection mdl_con2;
1055--echo # Prepare for blocking RENAME TABLE.
1056lock tables t2 read;
1057--echo #
1058connection default;
1059--echo # Sending:
1060--send rename table t1 to t2;
1061--echo #
1062connection mdl_con1;
1063--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
1064let $wait_condition=
1065select count(*) = 1 from information_schema.processlist
1066where state = "Waiting for table metadata lock" and
1067      info = "rename table t1 to t2";
1068--source include/wait_condition.inc
1069--echo # Check that SU lock is incompatible with X lock.
1070--echo # Sending:
1071--send alter table t1 add primary key (c1);
1072--echo #
1073connection mdl_con2;
1074--echo # Check that the above ALTER statement is blocked
1075--echo # because of X lock.
1076let $wait_condition=
1077select count(*) = 1 from information_schema.processlist
1078where state = "Waiting for table metadata lock" and
1079      info = "alter table t1 add primary key (c1)";
1080--source include/wait_condition.inc
1081--echo # Unblock RENAME TABLE
1082unlock tables;
1083--echo #
1084connection default;
1085--echo # Reaping RENAME TABLE
1086--error ER_TABLE_EXISTS_ERROR
1087--reap
1088--echo #
1089connection mdl_con1;
1090--echo # Reaping ALTER.
1091--error ER_DUP_ENTRY
1092--reap
1093--echo #
1094--echo # Note that we can't easily check SNW vs X locks since
1095--echo # SNW is only used by ALTER TABLE after upgrading from SU
1096--echo # and SU is also incompatible with X.
1097--echo #
1098connection mdl_con2;
1099--echo # Prepare for blocking RENAME TABLE.
1100lock tables t2 read;
1101--echo #
1102connection default;
1103--echo # Sending:
1104--send rename table t1 to t2;
1105--echo #
1106connection mdl_con1;
1107--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
1108let $wait_condition=
1109select count(*) = 1 from information_schema.processlist
1110where state = "Waiting for table metadata lock" and
1111      info = "rename table t1 to t2";
1112--source include/wait_condition.inc
1113--echo # Check that SNRW lock is incompatible with X lock.
1114--echo # Sending:
1115--send lock table t1 write;
1116--echo #
1117connection mdl_con2;
1118--echo # Check that the above LOCK TABLE statement is blocked
1119--echo # because of X lock.
1120let $wait_condition=
1121select count(*) = 1 from information_schema.processlist
1122where state = "Waiting for table metadata lock" and
1123      info = "lock table t1 write";
1124--source include/wait_condition.inc
1125--echo # Unblock RENAME TABLE
1126unlock tables;
1127--echo #
1128connection default;
1129--echo # Reaping RENAME TABLE
1130--error ER_TABLE_EXISTS_ERROR
1131--reap
1132--echo #
1133connection mdl_con1;
1134--echo # Reaping LOCK TABLE.
1135--reap
1136unlock tables;
1137--echo #
1138connection mdl_con2;
1139--echo # Prepare for blocking RENAME TABLE.
1140lock tables t2 read;
1141--echo #
1142connection default;
1143--echo # Sending:
1144--send rename table t1 to t2;
1145--echo #
1146connection mdl_con1;
1147--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
1148let $wait_condition=
1149select count(*) = 1 from information_schema.processlist
1150where state = "Waiting for table metadata lock" and
1151      info = "rename table t1 to t2";
1152--source include/wait_condition.inc
1153--echo # Check that X lock is incompatible with X lock.
1154--echo # Sending:
1155--send rename table t1 to t3;
1156--echo #
1157connection mdl_con2;
1158--echo # Check that the above RENAME statement is blocked
1159--echo # because of X lock.
1160let $wait_condition=
1161select count(*) = 1 from information_schema.processlist
1162where state = "Waiting for table metadata lock" and
1163      info = "rename table t1 to t3";
1164--source include/wait_condition.inc
1165--echo # Unblock RENAME TABLE
1166unlock tables;
1167--echo #
1168connection default;
1169--echo # Reaping RENAME TABLE
1170--error ER_TABLE_EXISTS_ERROR
1171--reap
1172--echo #
1173connection mdl_con1;
1174--echo # Reaping RENAME.
1175--reap
1176rename table t3 to t1;
1177
1178--echo #
1179--echo # B) Now let us test compatibility in cases when both locks
1180--echo #    are pending. I.e. let us test rules for priorities between
1181--echo #    different types of metadata locks.
1182--echo #
1183--echo #    Note: No tests for pending SU lock as this lock requires
1184--echo #          even stronger active or pending lock.
1185--echo #
1186
1187--echo #
1188connection mdl_con2;
1189--echo #
1190--echo # 1) Check compatibility for pending SNW lock.
1191--echo #
1192--echo # Acquire SW lock in order to create pending SNW lock later.
1193begin;
1194insert into t1 values (1);
1195--echo #
1196connection default;
1197--echo # Add pending SNW lock.
1198--echo # Sending:
1199--send alter table t1 add primary key (c1);
1200--echo #
1201connection mdl_con1;
1202--echo # Check that ALTER TABLE is waiting with pending SNW lock.
1203let $wait_condition=
1204select count(*) = 1 from information_schema.processlist
1205where state = "Waiting for table metadata lock" and
1206      info = "alter table t1 add primary key (c1)";
1207--source include/wait_condition.inc
1208--echo # Check that S, SH and SR locks are compatible with pending SNW
1209handler t1 open t;
1210handler t close;
1211select column_name from information_schema.columns where
1212  table_schema='test' and table_name='t1';
1213select count(*) from t1;
1214--echo # Check that SW is incompatible with pending SNW
1215--echo # Sending:
1216--send delete from t1 limit 1;
1217--echo #
1218connection mdl_con2;
1219--echo # Check that the above DELETE is blocked because of pending SNW lock.
1220let $wait_condition=
1221select count(*) = 1 from information_schema.processlist
1222where state = "Waiting for table metadata lock" and
1223      info = "delete from t1 limit 1";
1224--source include/wait_condition.inc
1225--echo # Unblock ALTER TABLE.
1226commit;
1227--echo #
1228connection default;
1229--echo # Reaping ALTER.
1230--error ER_DUP_ENTRY
1231--reap
1232--echo #
1233connection mdl_con1;
1234--echo # Reaping DELETE.
1235--reap
1236--echo #
1237--echo # We can't do similar check for SNW, SNRW and X locks because
1238--echo # they will also be blocked by active SW lock.
1239--echo #
1240--echo #
1241connection mdl_con2;
1242--echo #
1243--echo # 2) Check compatibility for pending SNRW lock.
1244--echo #
1245--echo # Acquire SR lock in order to create pending SNRW lock.
1246begin;
1247select count(*) from t1;
1248--echo #
1249connection default;
1250--echo # Add pending SNRW lock.
1251--echo # Sending:
1252--send lock table t1 write;
1253--echo #
1254connection mdl_con1;
1255--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
1256let $wait_condition=
1257select count(*) = 1 from information_schema.processlist
1258where state = "Waiting for table metadata lock" and
1259      info = "lock table t1 write";
1260--source include/wait_condition.inc
1261--echo # Check that S and SH locks are compatible with pending SNRW
1262select column_name from information_schema.columns where
1263  table_schema='test' and table_name='t1';
1264--echo # Check that SR is incompatible with pending SNRW
1265--echo # Sending:
1266--send select count(*) from t1;
1267--echo #
1268connection mdl_con2;
1269--echo # Check that the above SELECT is blocked because of pending SNRW lock.
1270let $wait_condition=
1271select count(*) = 1 from information_schema.processlist
1272where state = "Waiting for table metadata lock" and
1273      info = "select count(*) from t1";
1274--source include/wait_condition.inc
1275--echo # Unblock LOCK TABLE.
1276commit;
1277--echo #
1278connection default;
1279--echo # Reaping LOCK TABLE.
1280--reap
1281unlock tables;
1282--echo #
1283connection mdl_con1;
1284--echo # Reaping SELECT.
1285--reap
1286--echo # Restore pending SNRW lock.
1287--echo #
1288connection mdl_con2;
1289begin;
1290select count(*) from t1;
1291--echo #
1292connection default;
1293--echo # Sending:
1294--send lock table t1 write;
1295--echo #
1296connection mdl_con1;
1297--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
1298let $wait_condition=
1299select count(*) = 1 from information_schema.processlist
1300where state = "Waiting for table metadata lock" and
1301      info = "lock table t1 write";
1302--source include/wait_condition.inc
1303--echo # Check that SW is incompatible with pending SNRW
1304--echo # Sending:
1305--send insert into t1 values (1);
1306--echo #
1307connection mdl_con2;
1308--echo # Check that the above INSERT is blocked because of pending SNRW lock.
1309let $wait_condition=
1310select count(*) = 1 from information_schema.processlist
1311where state = "Waiting for table metadata lock" and
1312      info = "insert into t1 values (1)";
1313--source include/wait_condition.inc
1314--echo # Unblock LOCK TABLE.
1315commit;
1316--echo #
1317connection default;
1318--echo # Reaping LOCK TABLE.
1319--reap
1320unlock tables;
1321--echo #
1322connection mdl_con1;
1323--echo # Reaping INSERT.
1324--reap
1325--echo # Restore pending SNRW lock.
1326--echo #
1327connection mdl_con2;
1328begin;
1329select count(*) from t1;
1330--echo #
1331connection default;
1332--echo # Sending:
1333--send lock table t1 write;
1334--echo #
1335connection mdl_con1;
1336--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
1337let $wait_condition=
1338select count(*) = 1 from information_schema.processlist
1339where state = "Waiting for table metadata lock" and
1340      info = "lock table t1 write";
1341--source include/wait_condition.inc
1342--echo # Check that SNW is compatible with pending SNRW
1343--echo # So ALTER TABLE statements are not starved by LOCK TABLEs.
1344--error ER_DUP_ENTRY
1345alter table t1 add primary key (c1);
1346--echo #
1347connection mdl_con2;
1348--echo # Unblock LOCK TABLE.
1349commit;
1350--echo #
1351connection default;
1352--echo # Reaping LOCK TABLE.
1353--reap
1354unlock tables;
1355--echo #
1356--echo # We can't do similar check for SNRW and X locks because
1357--echo # they will also be blocked by active SR lock.
1358--echo #
1359--echo #
1360connection mdl_con2;
1361--echo #
1362--echo # 3) Check compatibility for pending X lock.
1363--echo #
1364--echo # Acquire SR lock in order to create pending X lock.
1365begin;
1366select count(*) from t1;
1367--echo #
1368connection default;
1369--echo # Add pending X lock.
1370--echo # Sending:
1371--send rename table t1 to t2;
1372--echo #
1373connection mdl_con1;
1374--echo # Check that RENAME TABLE is waiting with pending X lock.
1375let $wait_condition=
1376select count(*) = 1 from information_schema.processlist
1377where state = "Waiting for table metadata lock" and
1378      info = "rename table t1 to t2";
1379--source include/wait_condition.inc
1380--echo # Check that SH locks are compatible with pending X
1381select column_name from information_schema.columns where
1382  table_schema='test' and table_name='t1';
1383--echo # Check that S is incompatible with pending X
1384--echo # Sending:
1385--send handler t1 open;
1386--echo #
1387connection mdl_con2;
1388--echo # Check that the above HANDLER OPEN is blocked because of pending X lock.
1389let $wait_condition=
1390select count(*) = 1 from information_schema.processlist
1391where state = "Waiting for table metadata lock" and
1392      info = "handler t1 open";
1393--source include/wait_condition.inc
1394--echo # Unblock RENAME TABLE.
1395commit;
1396--echo #
1397connection default;
1398--echo # Reaping RENAME TABLE.
1399--error ER_TABLE_EXISTS_ERROR
1400--reap
1401--echo #
1402connection mdl_con1;
1403--echo # Reaping HANDLER t1 OPEN.
1404--reap
1405handler t1 close;
1406--echo # Restore pending X lock.
1407--echo #
1408connection mdl_con2;
1409begin;
1410select count(*) from t1;
1411--echo #
1412connection default;
1413--echo # Add pending X lock.
1414--echo # Sending:
1415--send rename table t1 to t2;
1416--echo #
1417connection mdl_con1;
1418--echo # Check that RENAME TABLE is waiting with pending X lock.
1419let $wait_condition=
1420select count(*) = 1 from information_schema.processlist
1421where state = "Waiting for table metadata lock" and
1422      info = "rename table t1 to t2";
1423--source include/wait_condition.inc
1424--echo # Check that SR is incompatible with pending X
1425--echo # Sending:
1426--send select count(*) from t1;
1427--echo #
1428connection mdl_con2;
1429--echo # Check that the above SELECT is blocked because of pending X lock.
1430let $wait_condition=
1431select count(*) = 1 from information_schema.processlist
1432where state = "Waiting for table metadata lock" and
1433      info = "select count(*) from t1";
1434--source include/wait_condition.inc
1435--echo # Unblock RENAME TABLE.
1436commit;
1437--echo #
1438connection default;
1439--echo # Reaping RENAME TABLE.
1440--error ER_TABLE_EXISTS_ERROR
1441--reap
1442--echo #
1443connection mdl_con1;
1444--echo # Reaping SELECT.
1445--reap
1446--echo # Restore pending X lock.
1447--echo #
1448connection mdl_con2;
1449begin;
1450select count(*) from t1;
1451--echo #
1452connection default;
1453--echo # Add pending X lock.
1454--echo # Sending:
1455--send rename table t1 to t2;
1456--echo #
1457connection mdl_con1;
1458--echo # Check that RENAME TABLE is waiting with pending X lock.
1459let $wait_condition=
1460select count(*) = 1 from information_schema.processlist
1461where state = "Waiting for table metadata lock" and
1462      info = "rename table t1 to t2";
1463--source include/wait_condition.inc
1464--echo # Check that SW is incompatible with pending X
1465--echo # Sending:
1466--send delete from t1 limit 1;
1467--echo #
1468connection mdl_con2;
1469--echo # Check that the above DELETE is blocked because of pending X lock.
1470let $wait_condition=
1471select count(*) = 1 from information_schema.processlist
1472where state = "Waiting for table metadata lock" and
1473      info = "delete from t1 limit 1";
1474--source include/wait_condition.inc
1475--echo # Unblock RENAME TABLE.
1476commit;
1477--echo #
1478connection default;
1479--echo # Reaping RENAME TABLE.
1480--error ER_TABLE_EXISTS_ERROR
1481--reap
1482--echo #
1483connection mdl_con1;
1484--echo # Reaping DELETE.
1485--reap
1486--echo # Restore pending X lock.
1487--echo #
1488connection mdl_con2;
1489begin;
1490select count(*) from t1;
1491--echo #
1492connection default;
1493--echo # Add pending X lock.
1494--echo # Sending:
1495--send rename table t1 to t2;
1496--echo #
1497connection mdl_con1;
1498--echo # Check that RENAME TABLE is waiting with pending X lock.
1499let $wait_condition=
1500select count(*) = 1 from information_schema.processlist
1501where state = "Waiting for table metadata lock" and
1502      info = "rename table t1 to t2";
1503--source include/wait_condition.inc
1504--echo # Check that SNW is incompatible with pending X
1505--echo # Sending:
1506--send alter table t1 add primary key (c1);
1507--echo #
1508connection mdl_con2;
1509--echo # Check that the above ALTER TABLE is blocked because of pending X lock.
1510let $wait_condition=
1511select count(*) = 1 from information_schema.processlist
1512where state = "Waiting for table metadata lock" and
1513      info = "alter table t1 add primary key (c1)";
1514--source include/wait_condition.inc
1515--echo # Unblock RENAME TABLE.
1516commit;
1517--echo #
1518connection default;
1519--echo # Reaping RENAME TABLE.
1520--error ER_TABLE_EXISTS_ERROR
1521--reap
1522--echo #
1523connection mdl_con1;
1524--echo # Reaping ALTER TABLE.
1525--error ER_DUP_ENTRY
1526--reap
1527--echo # Restore pending X lock.
1528--echo #
1529connection mdl_con2;
1530handler t1 open;
1531--echo #
1532connection default;
1533--echo # Add pending X lock.
1534--echo # Sending:
1535--send rename table t1 to t2;
1536--echo #
1537connection mdl_con1;
1538--echo # Check that RENAME TABLE is waiting with pending X lock.
1539let $wait_condition=
1540select count(*) = 1 from information_schema.processlist
1541where state = "Waiting for table metadata lock" and
1542      info = "rename table t1 to t2";
1543--source include/wait_condition.inc
1544--echo # Check that SNRW is incompatible with pending X
1545--echo # Sending:
1546--send lock table t1 write;
1547--echo #
1548connection mdl_con3;
1549--echo # Check that the above LOCK TABLES is blocked because of pending X lock.
1550let $wait_condition=
1551select count(*) = 1 from information_schema.processlist
1552where state = "Waiting for table metadata lock" and
1553      info = "lock table t1 write";
1554--source include/wait_condition.inc
1555--echo #
1556connection mdl_con2;
1557--echo # Unblock RENAME TABLE.
1558handler t1 close;
1559--echo #
1560connection default;
1561--echo # Reaping RENAME TABLE.
1562--error ER_TABLE_EXISTS_ERROR
1563--reap
1564--echo #
1565connection mdl_con1;
1566--echo # Reaping LOCK TABLES.
1567--reap
1568unlock tables;
1569--echo #
1570connection default;
1571
1572--echo #
1573--echo #
1574--echo # C) Now let us test how type-of-operation locks are handled in
1575--echo #    transactional context. Obviously we are mostly interested
1576--echo #    in conflicting types of locks.
1577--echo #
1578--echo #    Note: No tests for active/pending SU lock since
1579--echo #          ALTER TABLE is in its own transaction.
1580--echo #
1581
1582--echo #
1583--echo # 1) Let us check how various locks used within transactional
1584--echo #    context interact with active/pending SNW lock.
1585--echo #
1586--echo #    We start with case when we are acquiring lock on the table
1587--echo #    which was not used in the transaction before.
1588begin;
1589select count(*) from t1;
1590--echo #
1591connection mdl_con1;
1592--echo # Create an active SNW lock on t2.
1593--echo # We have to use DEBUG_SYNC facility as otherwise SNW lock
1594--echo # will be immediately released (or upgraded to X lock).
1595insert into t2 values (1), (1);
1596set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
1597--echo # Sending:
1598--send alter table t2 add primary key (c1), algorithm=copy, lock=shared;
1599--echo #
1600connection default;
1601set debug_sync= 'now WAIT_FOR locked';
1602--echo # SR lock should be acquired without any waiting.
1603select count(*) from t2;
1604commit;
1605--echo # Now let us check that we will wait in case of SW lock.
1606begin;
1607select count(*) from t1;
1608--echo # Sending:
1609--send insert into t2 values (1);
1610--echo #
1611connection mdl_con2;
1612--echo # Check that the above INSERT is blocked.
1613let $wait_condition=
1614select count(*) = 1 from information_schema.processlist
1615where state = "Waiting for table metadata lock" and
1616      info = "insert into t2 values (1)";
1617--source include/wait_condition.inc
1618--echo # Unblock ALTER TABLE and thus INSERT.
1619set debug_sync= 'now SIGNAL finish';
1620--echo #
1621connection mdl_con1;
1622--echo # Reap ALTER TABLE.
1623--error ER_DUP_ENTRY
1624--reap
1625--echo #
1626connection default;
1627--echo # Reap INSERT.
1628--reap
1629commit;
1630--echo #
1631--echo # Now let us see what happens when we are acquiring lock on the table
1632--echo # which is already used in transaction.
1633--echo #
1634--echo # *) First, case when transaction which has SR lock on the table also
1635--echo #    locked in SNW mode acquires yet another SR lock and then tries
1636--echo #    to acquire SW lock.
1637begin;
1638select count(*) from t1;
1639--echo #
1640connection mdl_con1;
1641--echo # Create an active SNW lock on t1.
1642set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
1643--echo # Sending:
1644--send alter table t1 add primary key (c1), algorithm=copy, lock=shared;
1645--echo #
1646connection default;
1647set debug_sync= 'now WAIT_FOR locked';
1648--echo # We should still be able to get SR lock without waiting.
1649select count(*) from t1;
1650--echo # Since the above ALTER TABLE is not upgrading SNW lock to X by waiting
1651--echo # for SW lock we won't create deadlock.
1652--echo # So the below INSERT should not end-up with ER_LOCK_DEADLOCK error.
1653--echo # Sending:
1654--send insert into t1 values (1);
1655--echo #
1656connection mdl_con2;
1657--echo # Check that the above INSERT is blocked.
1658let $wait_condition=
1659select count(*) = 1 from information_schema.processlist
1660where state = "Waiting for table metadata lock" and
1661      info = "insert into t1 values (1)";
1662--source include/wait_condition.inc
1663--echo # Unblock ALTER TABLE and thus INSERT.
1664set debug_sync= 'now SIGNAL finish';
1665--echo #
1666connection mdl_con1;
1667--echo # Reap ALTER TABLE.
1668--error ER_DUP_ENTRY
1669--reap
1670--echo #
1671connection default;
1672--echo # Reap INSERT.
1673--reap
1674commit;
1675--echo #
1676--echo # **) Now test in which transaction that has SW lock on the table
1677--echo #     against which there is pending SNW lock acquires SR and SW
1678--echo #     locks on this table.
1679--echo #
1680begin;
1681insert into t1 values (1);
1682--echo #
1683connection mdl_con1;
1684--echo # Create pending SNW lock on t1.
1685--echo # Sending:
1686--send alter table t1 add primary key (c1);
1687--echo #
1688connection default;
1689--echo # Wait until ALTER TABLE starts waiting for SNW lock.
1690let $wait_condition=
1691select count(*) = 1 from information_schema.processlist
1692where state = "Waiting for table metadata lock" and
1693      info = "alter table t1 add primary key (c1)";
1694--source include/wait_condition.inc
1695--echo # We should still be able to get both SW and SR locks without waiting.
1696select count(*) from t1;
1697delete from t1 limit 1;
1698--echo # Unblock ALTER TABLE.
1699commit;
1700--echo #
1701connection mdl_con1;
1702--echo # Reap ALTER TABLE.
1703--error ER_DUP_ENTRY
1704--reap
1705--echo #
1706connection default;
1707--echo #
1708--echo # 2) Now similar tests for active SNW lock which is being upgraded
1709--echo #    to X lock.
1710--echo #
1711--echo #    Again we start with case when we are acquiring lock on the
1712--echo #    table which was not used in the transaction before.
1713begin;
1714select count(*) from t1;
1715--echo #
1716connection mdl_con2;
1717--echo # Start transaction which will prevent SNW -> X upgrade from
1718--echo # completing immediately.
1719begin;
1720select count(*) from t2;
1721--echo #
1722connection mdl_con1;
1723--echo # Create SNW lock pending upgrade to X on t2.
1724--echo # Sending:
1725--send alter table t2 add column c2 int;
1726--echo #
1727connection default;
1728--echo # Wait until ALTER TABLE starts waiting X lock.
1729let $wait_condition=
1730select count(*) = 1 from information_schema.processlist
1731where state = "Waiting for table metadata lock" and
1732      info = "alter table t2 add column c2 int";
1733--source include/wait_condition.inc
1734--echo # Check that attempt to acquire SR lock on t2 causes waiting.
1735--echo # Sending:
1736--send select count(*) from t2;
1737--echo #
1738connection mdl_con2;
1739--echo # Check that the above SELECT is blocked.
1740let $wait_condition=
1741select count(*) = 1 from information_schema.processlist
1742where state = "Waiting for table metadata lock" and
1743      info = "select count(*) from t2";
1744--source include/wait_condition.inc
1745--echo # Unblock ALTER TABLE.
1746commit;
1747--echo #
1748connection mdl_con1;
1749--echo # Reap ALTER TABLE.
1750--reap
1751--echo #
1752connection default;
1753--echo # Reap SELECT.
1754--reap
1755commit;
1756--echo # Do similar check for SW lock.
1757begin;
1758select count(*) from t1;
1759--echo #
1760connection mdl_con2;
1761--echo # Start transaction which will prevent SNW -> X upgrade from
1762--echo # completing immediately.
1763begin;
1764select count(*) from t2;
1765--echo #
1766connection mdl_con1;
1767--echo # Create SNW lock pending upgrade to X on t2.
1768--echo # Sending:
1769--send alter table t2 drop column c2;
1770--echo #
1771connection default;
1772--echo # Wait until ALTER TABLE starts waiting X lock.
1773let $wait_condition=
1774select count(*) = 1 from information_schema.processlist
1775where state = "Waiting for table metadata lock" and
1776      info = "alter table t2 drop column c2";
1777--source include/wait_condition.inc
1778--echo # Check that attempt to acquire SW lock on t2 causes waiting.
1779--echo # Sending:
1780--send insert into t2 values (1);
1781--echo #
1782connection mdl_con2;
1783--echo # Check that the above INSERT is blocked.
1784let $wait_condition=
1785select count(*) = 1 from information_schema.processlist
1786where state = "Waiting for table metadata lock" and
1787      info = "insert into t2 values (1)";
1788--source include/wait_condition.inc
1789--echo # Unblock ALTER TABLE.
1790commit;
1791--echo #
1792connection mdl_con1;
1793--echo # Reap ALTER TABLE.
1794--reap
1795--echo #
1796connection default;
1797--echo # Reap INSERT.
1798--reap
1799commit;
1800--echo #
1801--echo # Test for the case in which we are acquiring lock on the table
1802--echo # which is already used in transaction.
1803--echo #
1804begin;
1805select count(*) from t1;
1806--echo #
1807connection mdl_con1;
1808--echo # Create SNW lock pending upgrade to X.
1809--echo # Sending:
1810--send alter table t1 add column c2 int;
1811--echo #
1812connection default;
1813--echo # Wait until ALTER TABLE starts waiting X lock.
1814let $wait_condition=
1815select count(*) = 1 from information_schema.processlist
1816where state = "Waiting for table metadata lock" and
1817      info = "alter table t1 add column c2 int";
1818--source include/wait_condition.inc
1819--echo # Check that transaction is still able to acquire SR lock.
1820select count(*) from t1;
1821--echo # Waiting trying to acquire SW lock will cause deadlock and
1822--echo # therefore should cause an error.
1823--error ER_LOCK_DEADLOCK
1824delete from t1 limit 1;
1825--echo # Unblock ALTER TABLE.
1826commit;
1827--echo #
1828connection mdl_con1;
1829--echo # Reap ALTER TABLE.
1830--reap
1831--echo #
1832connection default;
1833--echo #
1834--echo # 3) Check how various locks used within transactional context
1835--echo #    interact with active/pending SNRW lock.
1836--echo #
1837--echo #    Once again we start with case when we are acquiring lock on
1838--echo #    the table which was not used in the transaction before.
1839begin;
1840select count(*) from t1;
1841--echo #
1842connection mdl_con1;
1843lock table t2 write;
1844--echo #
1845connection default;
1846--echo # Attempt to acquire SR should be blocked. It should
1847--echo # not cause errors as it does not creates deadlock.
1848--echo # Sending:
1849--send select count(*) from t2;
1850--echo #
1851connection mdl_con1;
1852--echo # Check that the above SELECT is blocked
1853let $wait_condition=
1854select count(*) = 1 from information_schema.processlist
1855where state = "Waiting for table metadata lock" and
1856      info = "select count(*) from t2";
1857--source include/wait_condition.inc
1858--echo # Unblock SELECT.
1859unlock tables;
1860--echo #
1861connection default;
1862--echo # Reap SELECT.
1863--reap
1864commit;
1865--echo # Repeat the same test for SW lock.
1866begin;
1867select count(*) from t1;
1868--echo #
1869connection mdl_con1;
1870lock table t2 write;
1871--echo #
1872connection default;
1873--echo # Again attempt to acquire SW should be blocked and should
1874--echo # not cause any errors.
1875--echo # Sending:
1876--send delete from t2 limit 1;
1877--echo #
1878connection mdl_con1;
1879--echo # Check that the above DELETE is blocked
1880let $wait_condition=
1881select count(*) = 1 from information_schema.processlist
1882where state = "Waiting for table metadata lock" and
1883      info = "delete from t2 limit 1";
1884--source include/wait_condition.inc
1885--echo # Unblock DELETE.
1886unlock tables;
1887--echo #
1888connection default;
1889--echo # Reap DELETE.
1890--reap
1891commit;
1892--echo #
1893--echo # Now coverage for the case in which we are acquiring lock on
1894--echo # the table which is already used in transaction and against
1895--echo # which there is a pending SNRW lock request.
1896--echo #
1897--echo # *) Let us start with case when transaction has only a SR lock.
1898--echo #
1899begin;
1900select count(*) from t1;
1901--echo #
1902connection mdl_con1;
1903--echo # Sending:
1904--send lock table t1 write;
1905--echo #
1906connection default;
1907--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
1908let $wait_condition=
1909select count(*) = 1 from information_schema.processlist
1910where state = "Waiting for table metadata lock" and
1911      info = "lock table t1 write";
1912--source include/wait_condition.inc
1913--echo # Check that another instance of SR lock is granted without waiting.
1914select count(*) from t1;
1915--echo # Attempt to wait for SW lock will lead to deadlock, thus
1916--echo # the below statement should end with ER_LOCK_DEADLOCK error.
1917--error ER_LOCK_DEADLOCK
1918delete from t1 limit 1;
1919--echo # Unblock LOCK TABLES.
1920commit;
1921--echo #
1922connection mdl_con1;
1923--echo # Reap LOCK TABLES.
1924--reap
1925unlock tables;
1926--echo #
1927connection default;
1928--echo #
1929--echo # **) Now case when transaction has a SW lock.
1930--echo #
1931begin;
1932delete from t1 limit 1;
1933--echo #
1934connection mdl_con1;
1935--echo # Sending:
1936--send lock table t1 write;
1937--echo #
1938connection default;
1939--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
1940let $wait_condition=
1941select count(*) = 1 from information_schema.processlist
1942where state = "Waiting for table metadata lock" and
1943      info = "lock table t1 write";
1944--source include/wait_condition.inc
1945--echo # Check that both SR and SW locks are granted without waiting
1946--echo # and errors.
1947select count(*) from t1;
1948insert into t1 values (1, 1);
1949--echo # Unblock LOCK TABLES.
1950commit;
1951--echo #
1952connection mdl_con1;
1953--echo # Reap LOCK TABLES.
1954--reap
1955unlock tables;
1956--echo #
1957connection default;
1958--echo #
1959--echo # 4) Check how various locks used within transactional context
1960--echo #    interact with active/pending X lock.
1961--echo #
1962--echo #    As usual we start with case when we are acquiring lock on
1963--echo #    the table which was not used in the transaction before.
1964begin;
1965select count(*) from t1;
1966--echo #
1967connection mdl_con2;
1968--echo # Start transaction which will prevent X lock from going away
1969--echo # immediately.
1970begin;
1971select count(*) from t2;
1972--echo #
1973connection mdl_con1;
1974--echo # Create pending X lock on t2.
1975--echo # Sending:
1976--send rename table t2 to t3;
1977--echo #
1978connection default;
1979--echo # Wait until RENAME TABLE starts waiting with pending X lock.
1980let $wait_condition=
1981select count(*) = 1 from information_schema.processlist
1982where state = "Waiting for table metadata lock" and
1983      info = "rename table t2 to t3";
1984--source include/wait_condition.inc
1985--echo # Check that attempt to acquire SR lock on t2 causes waiting.
1986--echo # Sending:
1987--send select count(*) from t2;
1988--echo #
1989connection mdl_con2;
1990--echo # Check that the above SELECT is blocked.
1991let $wait_condition=
1992select count(*) = 1 from information_schema.processlist
1993where state = "Waiting for table metadata lock" and
1994      info = "select count(*) from t2";
1995--source include/wait_condition.inc
1996--echo # Unblock RENAME TABLE.
1997commit;
1998--echo #
1999connection mdl_con1;
2000--echo # Reap RENAME TABLE.
2001--reap
2002--echo #
2003connection default;
2004--echo # Reap SELECT.
2005--error ER_NO_SUCH_TABLE
2006--reap
2007commit;
2008rename table t3 to t2;
2009--echo # The same test for SW lock.
2010begin;
2011select count(*) from t1;
2012--echo #
2013connection mdl_con2;
2014--echo # Start transaction which will prevent X lock from going away
2015--echo # immediately.
2016begin;
2017select count(*) from t2;
2018--echo #
2019connection mdl_con1;
2020--echo # Create pending X lock on t2.
2021--echo # Sending:
2022--send rename table t2 to t3;
2023--echo #
2024connection default;
2025--echo # Wait until RENAME TABLE starts waiting with pending X lock.
2026let $wait_condition=
2027select count(*) = 1 from information_schema.processlist
2028where state = "Waiting for table metadata lock" and
2029      info = "rename table t2 to t3";
2030--source include/wait_condition.inc
2031--echo # Check that attempt to acquire SW lock on t2 causes waiting.
2032--echo # Sending:
2033--send delete from t2 limit 1;
2034--echo #
2035connection mdl_con2;
2036--echo # Check that the above DELETE is blocked.
2037let $wait_condition=
2038select count(*) = 1 from information_schema.processlist
2039where state = "Waiting for table metadata lock" and
2040      info = "delete from t2 limit 1";
2041--source include/wait_condition.inc
2042--echo # Unblock RENAME TABLE.
2043commit;
2044--echo #
2045connection mdl_con1;
2046--echo # Reap RENAME TABLE.
2047--reap
2048--echo #
2049connection default;
2050--echo # Reap DELETE.
2051--error ER_NO_SUCH_TABLE
2052--reap
2053commit;
2054rename table t3 to t2;
2055--echo #
2056--echo # Coverage for the case in which we are acquiring lock on
2057--echo # the table which is already used in transaction and against
2058--echo # which there is a pending X lock request.
2059--echo #
2060--echo # *) The first case is when transaction has only a SR lock.
2061--echo #
2062begin;
2063select count(*) from t1;
2064--echo #
2065connection mdl_con1;
2066--echo # Sending:
2067--send rename table t1 to t2;
2068--echo #
2069connection default;
2070--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
2071let $wait_condition=
2072select count(*) = 1 from information_schema.processlist
2073where state = "Waiting for table metadata lock" and
2074      info = "rename table t1 to t2";
2075--source include/wait_condition.inc
2076--echo # Check that another instance of SR lock is granted without waiting.
2077select count(*) from t1;
2078--echo # Attempt to wait for SW lock will lead to deadlock, thus
2079--echo # the below statement should end with ER_LOCK_DEADLOCK error.
2080--error ER_LOCK_DEADLOCK
2081delete from t1 limit 1;
2082--echo # Unblock RENAME TABLE.
2083commit;
2084--echo #
2085connection mdl_con1;
2086--echo # Reap RENAME TABLE.
2087--error ER_TABLE_EXISTS_ERROR
2088--reap
2089--echo #
2090connection default;
2091--echo #
2092--echo # **) The second case is when transaction has a SW lock.
2093--echo #
2094begin;
2095delete from t1 limit 1;
2096--echo #
2097connection mdl_con1;
2098--echo # Sending:
2099--send rename table t1 to t2;
2100--echo #
2101connection default;
2102--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
2103let $wait_condition=
2104select count(*) = 1 from information_schema.processlist
2105where state = "Waiting for table metadata lock" and
2106      info = "rename table t1 to t2";
2107--source include/wait_condition.inc
2108--echo # Check that both SR and SW locks are granted without waiting
2109--echo # and errors.
2110select count(*) from t1;
2111insert into t1 values (1, 1);
2112--echo # Unblock RENAME TABLE.
2113commit;
2114--echo #
2115connection mdl_con1;
2116--echo # Reap RENAME TABLE.
2117--error ER_TABLE_EXISTS_ERROR
2118--reap
2119--echo #
2120connection default;
2121
2122--echo # Clean-up.
2123disconnect mdl_con1;
2124disconnect mdl_con2;
2125disconnect mdl_con3;
2126set debug_sync= 'RESET';
2127drop table t1, t2;
2128
2129--echo #
2130--echo # Test coverage for basic deadlock detection in metadata
2131--echo # locking subsystem.
2132--echo #
2133--disable_warnings
2134drop tables if exists t0, t1, t2, t3, t4, t5;
2135--enable_warnings
2136set debug_sync= 'RESET';
2137
2138connect(deadlock_con1,localhost,root,,);
2139connect(deadlock_con2,localhost,root,,);
2140connect(deadlock_con3,localhost,root,,);
2141connection default;
2142create table t1 (i int);
2143create table t2 (j int);
2144create table t3 (k int);
2145create table t4 (k int);
2146
2147--echo #
2148--echo # Test for the case in which no deadlock occurs.
2149--echo #
2150
2151--echo #
2152connection deadlock_con1;
2153begin;
2154insert into t1 values (1);
2155
2156--echo #
2157connection deadlock_con2;
2158begin;
2159insert into t2 values (1);
2160
2161--echo #
2162connection default;
2163--echo # Send:
2164--send rename table t2 to t0, t3 to t2, t0 to t3;
2165
2166--echo #
2167connection deadlock_con1;
2168--echo # Wait until the above RENAME TABLE is blocked because it has to wait
2169--echo # for 'deadlock_con2' which holds shared metadata lock on 't2'.
2170let $wait_condition=
2171  select count(*) = 1 from information_schema.processlist
2172  where state = "Waiting for table metadata lock" and
2173        info = "rename table t2 to t0, t3 to t2, t0 to t3";
2174--source include/wait_condition.inc
2175--echo # The below statement should wait for exclusive metadata lock
2176--echo # on 't2' to go away and should not produce ER_LOCK_DEADLOCK
2177--echo # as no deadlock is possible in this situation.
2178--echo # Send:
2179--send select * from t2;
2180
2181--echo #
2182connection deadlock_con2;
2183--echo # Wait until the above SELECT * FROM t2 is starts waiting
2184--echo # for an exclusive metadata lock to go away.
2185let $wait_condition=
2186  select count(*) = 1 from information_schema.processlist
2187  where state = "Waiting for table metadata lock" and
2188        info = "select * from t2";
2189--source include/wait_condition.inc
2190--echo #
2191--echo # Unblock RENAME TABLE by releasing shared metadata lock on t2.
2192commit;
2193
2194--echo #
2195connection default;
2196--echo # Reap RENAME TABLE.
2197--reap
2198
2199--echo #
2200connection deadlock_con1;
2201--echo # Reap SELECT.
2202--reap
2203
2204--echo #
2205connection default;
2206--echo #
2207--echo # Let us check that in the process of waiting for conflicting lock
2208--echo # on table 't2' to go away transaction in connection 'deadlock_con1'
2209--echo # has not released metadata lock on table 't1'.
2210--echo # Send:
2211--send rename table t1 to t0, t3 to t1, t0 to t3;
2212
2213--echo #
2214connection deadlock_con1;
2215--echo # Wait until the above RENAME TABLE is blocked because it has to wait
2216--echo # for 'deadlock_con1' which should still hold shared metadata lock on
2217--echo # table 't1'.
2218let $wait_condition=
2219  select count(*) = 1 from information_schema.processlist
2220  where state = "Waiting for table metadata lock" and
2221        info = "rename table t1 to t0, t3 to t1, t0 to t3";
2222--source include/wait_condition.inc
2223--echo # Commit transaction to unblock RENAME TABLE.
2224commit;
2225
2226--echo #
2227connection default;
2228--echo # Reap RENAME TABLE.
2229--reap
2230
2231--echo #
2232--echo # Test for case when deadlock occurs and should be detected immediately.
2233--echo #
2234
2235--echo #
2236connection deadlock_con1;
2237begin;
2238insert into t2 values (2);
2239
2240--echo #
2241connection default;
2242--echo # Send:
2243--send rename table t2 to t0, t1 to t2, t0 to t1;
2244
2245--echo #
2246connection deadlock_con1;
2247--echo # Wait until the above RENAME TABLE is blocked because it has to wait
2248--echo # for 'deadlock_con1' which holds shared metadata lock on 't2'.
2249let $wait_condition=
2250  select count(*) = 1 from information_schema.processlist
2251  where state = "Waiting for table metadata lock" and
2252        info = "rename table t2 to t0, t1 to t2, t0 to t1";
2253--source include/wait_condition.inc
2254--echo #
2255--echo # The below statement should not wait as doing so will cause deadlock.
2256--echo # Instead it should fail and emit ER_LOCK_DEADLOCK statement and
2257--echo # transaction should be rolled back.
2258--error ER_LOCK_DEADLOCK
2259select * from t1;
2260
2261--echo #
2262connection default;
2263--echo # Reap RENAME TABLE.
2264--reap
2265
2266--echo #
2267--echo # Test for the case in which deadlock also occurs but not immediately.
2268--echo #
2269
2270--echo #
2271connection deadlock_con1;
2272begin;
2273insert into t2 values (1);
2274
2275--echo #
2276connection default;
2277lock table t1 write;
2278
2279--echo #
2280connection deadlock_con1;
2281--echo # The below SELECT statement should wait for metadata lock
2282--echo # on table 't1' and should not produce ER_LOCK_DEADLOCK
2283--echo # immediately as no deadlock is possible at the moment.
2284--send select * from t1;
2285
2286--echo #
2287connection deadlock_con2;
2288--echo # Wait until the above SELECT * FROM t1 is starts waiting
2289--echo # for an UNRW metadata lock to go away.
2290let $wait_condition=
2291  select count(*) = 1 from information_schema.processlist
2292  where state = "Waiting for table metadata lock" and info = "select * from t1";
2293--source include/wait_condition.inc
2294
2295--echo # Send RENAME TABLE statement that will deadlock with the
2296--echo # SELECT statement and thus should abort the latter.
2297--send rename table t1 to t0, t2 to t1, t0 to t2;
2298
2299--echo #
2300connection default;
2301--echo # Wait till above RENAME TABLE is blocked while holding
2302--echo # pending X lock on t1.
2303let $wait_condition=
2304  select count(*) = 1 from information_schema.processlist
2305  where state = "Waiting for table metadata lock" and
2306        info = "rename table t1 to t0, t2 to t1, t0 to t2";
2307--source include/wait_condition.inc
2308--echo # Allow the above RENAME TABLE to acquire lock on t1 and
2309--echo # create pending lock on t2 thus creating deadlock.
2310unlock tables;
2311
2312--echo #
2313connection deadlock_con1;
2314--echo # Since the latest RENAME TABLE entered in deadlock with SELECT
2315--echo # statement the latter should be aborted and emit ER_LOCK_DEADLOCK
2316--echo # error and transaction should be rolled back.
2317--echo # Reap SELECT * FROM t1.
2318--error ER_LOCK_DEADLOCK
2319--reap
2320
2321--echo #
2322connection deadlock_con2;
2323--echo # Reap RENAME TABLE ... .
2324--reap;
2325
2326--echo #
2327connection default;
2328
2329drop tables t1, t2, t3, t4;
2330
2331--echo #
2332--echo # Now, test case which shows that deadlock detection empiric
2333--echo # also takes into account requests for metadata lock upgrade.
2334--echo #
2335create table t1 (i int);
2336insert into t1 values (1);
2337--echo # Avoid race which occurs when SELECT in 'deadlock_con1' connection
2338--echo # accesses table before the above INSERT unlocks the table and thus
2339--echo # its result becomes visible to other connections.
2340select * from t1;
2341
2342--echo #
2343connection deadlock_con1;
2344begin;
2345select * from t1;
2346
2347--echo #
2348connection default;
2349--echo # Send:
2350--send alter table t1 add column j int, rename to t2;
2351
2352--echo #
2353connection deadlock_con1;
2354--echo # Wait until the above ALTER TABLE ... RENAME acquires exclusive
2355--echo # metadata lock on 't2' and starts waiting for connection
2356--echo # 'deadlock_con1' which holds shared lock on 't1'.
2357let $wait_condition=
2358  select count(*) = 1 from information_schema.processlist
2359  where state = "Waiting for table metadata lock" and
2360        info = "alter table t1 add column j int, rename to t2";
2361--source include/wait_condition.inc
2362
2363--echo # The below statement should not wait as it will cause deadlock.
2364--echo # An appropriate error should be reported instead and transaction
2365--echo # should be rolled back.
2366--error ER_LOCK_DEADLOCK
2367select * from t2;
2368
2369--echo #
2370connection default;
2371--echo # Reap ALTER TABLE ... RENAME.
2372--reap
2373
2374drop table t2;
2375
2376--echo #
2377--echo # Test that in situation when MDL subsystem detects a deadlock
2378--echo # but it turns out that it can be resolved by backing-off locks
2379--echo # acquired by one of participating transactions (which is
2380--echo # possible when one of transactions consists only of currently
2381--echo # executed statement, e.g. in autocommit mode) no error is
2382--echo # reported.
2383--echo #
2384create table t1 (i int);
2385create table t2 (j int);
2386--echo # Ensure that the below SELECT stops once it has acquired metadata
2387--echo # lock on table 't2'.
2388set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
2389--echo # Sending:
2390--send select * from t2, t1
2391
2392--echo #
2393connection deadlock_con1;
2394--echo # Wait till SELECT acquires MDL on 't2' and starts waiting for signal.
2395set debug_sync= 'now WAIT_FOR locked';
2396--echo # Sending:
2397--send lock tables t1 write, t2 write
2398
2399--echo #
2400connection deadlock_con2;
2401--echo # Wait until LOCK TABLES acquires SNRW lock on 't1' and is blocked
2402--echo # while trying to acquire SNRW lock on 't1'.
2403let $wait_condition=
2404  select count(*) = 1 from information_schema.processlist
2405  where state = "Waiting for table metadata lock" and
2406        info = "lock tables t1 write, t2 write";
2407--source include/wait_condition.inc
2408--echo # Resume SELECT execution, this should eventually unblock LOCK TABLES.
2409set debug_sync= 'now SIGNAL finish';
2410
2411--echo #
2412connection deadlock_con1;
2413--echo # Reaping LOCK TABLES.
2414--reap
2415unlock tables;
2416
2417--echo #
2418connection default;
2419--echo # Reaping SELECT. It succeed and not report ER_LOCK_DEADLOCK error.
2420--reap
2421
2422drop tables t1, t2;
2423
2424--echo #
2425--echo # Test coverage for situation in which a race has happened
2426--echo # during deadlock detection process which led to unwarranted
2427--echo # ER_LOCK_DEADLOCK error.
2428--echo #
2429create table t1 (i int);
2430
2431--echo # Ensure that ALTER waits once it has acquired SNW lock.
2432set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL parked1 WAIT_FOR go1';
2433--echo # Sending:
2434--send alter table t1 add column j int
2435
2436--echo #
2437connection deadlock_con1;
2438--echo # Wait till ALTER acquires SNW lock and stops.
2439set debug_sync='now WAIT_FOR parked1';
2440--echo # Ensure that INSERT is paused once it detects that there is
2441--echo # a conflicting metadata lock so it has to wait, but before
2442--echo # deadlock detection is run.
2443set debug_sync='mdl_acquire_lock_wait SIGNAL parked2 WAIT_FOR go2';
2444--echo # Sending:
2445--send insert into t1 values ()
2446
2447--echo #
2448connection deadlock_con2;
2449--echo # Wait till INSERT is paused.
2450set debug_sync='now WAIT_FOR parked2';
2451--echo # Resume ALTER execution. Eventually it will release its
2452--echo # metadata lock and INSERT's request for SW lock will be
2453--echo # satisified.
2454set debug_sync='now SIGNAL go1';
2455
2456--echo #
2457connection default;
2458--echo # Reaping ALTER TABLE.
2459--reap
2460--echo # Add a new request for SNW lock to waiting graph.
2461--echo # Sending:
2462--send alter table t1 drop column j
2463
2464--echo #
2465connection deadlock_con2;
2466--echo # Wait until ALTER is blocked.
2467let $wait_condition=
2468  select count(*) = 1 from information_schema.processlist
2469  where state = "Waiting for table metadata lock" and
2470        info = "alter table t1 drop column j";
2471--source include/wait_condition.inc
2472--echo # Resume INSERT so it can start deadlock detection.
2473--echo #
2474--echo # At this point there is a discrepancy between the fact that INSERT's
2475--echo # SW lock is already satisfied, but INSERT's connection is still
2476--echo # marked as waiting for it. Looking for a loop in waiters graph
2477--echo # without additional checks has detected a deadlock (INSERT waits
2478--echo # for SW lock; which is not granted because of pending SNW lock from
2479--echo # ALTER; which waits for active SW lock from INSERT). Since requests
2480--echo # for SW and SNW locks have same weight ALTER was selected as a victim
2481--echo # and ended with ER_LOCK_DEADLOCK error.
2482set debug_sync='now SIGNAL go2';
2483
2484--echo #
2485connection deadlock_con1;
2486--echo # Reaping INSERT.
2487--reap
2488
2489--echo #
2490connection default;
2491--echo # Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK.
2492--reap
2493
2494drop table t1;
2495
2496--echo #
2497--echo # Now, test for a situation in which deadlock involves waiting not
2498--echo # only in MDL subsystem but also for TDC. Such deadlocks should be
2499--echo # successfully detected. If possible, they should be resolved without
2500--echo # resorting to ER_LOCK_DEADLOCK error.
2501--echo #
2502create table t1(i int);
2503create table t2(j int);
2504
2505--echo #
2506--echo # First, let us check how we handle a simple scenario involving
2507--echo # waits in MDL and TDC.
2508--echo #
2509set debug_sync= 'RESET';
2510
2511connection deadlock_con1;
2512--echo # Start a statement, which will acquire SR metadata lock on t1, open it
2513--echo # and then stop, before trying to acquire SW lock on t2 and opening it.
2514set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2515--echo # Sending:
2516--send select * from t1 where i in (select j from t2 for update)
2517
2518connection deadlock_con2;
2519--echo # Wait till the above SELECT stops.
2520set debug_sync='now WAIT_FOR parked';
2521--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2522--echo # SNW locks on t1 and t2 and wait till SELECT closes t1.
2523--echo # Sending:
2524send flush tables t1, t2 with read lock;
2525
2526connection deadlock_con3;
2527--echo # Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
2528--echo # for SELECT to close t1.
2529let $wait_condition=
2530  select count(*) = 1 from information_schema.processlist
2531  where state = "Waiting for table flush" and
2532        info = "flush tables t1, t2 with read lock";
2533--source include/wait_condition.inc
2534
2535--echo # Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
2536--echo # creating a deadlock. This deadlock should be detected and resolved
2537--echo # by backing-off SELECT. As a result FTWRL should be able to finish.
2538set debug_sync='now SIGNAL go';
2539
2540connection deadlock_con2;
2541--echo # Reap FLUSH TABLES WITH READ LOCK.
2542reap;
2543unlock tables;
2544
2545connection deadlock_con1;
2546--echo # Reap SELECT.
2547reap;
2548
2549--echo #
2550--echo # The same scenario with a slightly different order of events
2551--echo # which emphasizes that setting correct deadlock detector weights
2552--echo # for flush waits is important.
2553--echo #
2554set debug_sync= 'RESET';
2555
2556connection deadlock_con2;
2557set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
2558
2559--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2560--echo # SNW locks on t1 and t2 and wait on debug sync point.
2561--echo # Sending:
2562send flush tables t1, t2 with read lock;
2563
2564connection deadlock_con1;
2565--echo # Wait till FLUSH TABLE WITH READ LOCK stops.
2566set debug_sync='now WAIT_FOR parked';
2567
2568--echo # Start statement which will acquire SR metadata lock on t1, open
2569--echo # it and then will block while trying to acquire SW lock on t2.
2570--echo # Sending:
2571send select * from t1 where i in (select j from t2 for update);
2572
2573connection deadlock_con3;
2574--echo # Wait till the above SELECT blocks.
2575let $wait_condition=
2576  select count(*) = 1 from information_schema.processlist
2577  where state = "Waiting for table metadata lock" and
2578        info = "select * from t1 where i in (select j from t2 for update)";
2579--source include/wait_condition.inc
2580
2581--echo # Resume FLUSH TABLES, so it tries to flush t1, thus creating
2582--echo # a deadlock. This deadlock should be detected and resolved by
2583--echo # backing-off SELECT. As a result FTWRL should be able to finish.
2584set debug_sync='now SIGNAL go';
2585
2586connection deadlock_con2;
2587--echo # Reap FLUSH TABLES WITH READ LOCK.
2588reap;
2589unlock tables;
2590
2591connection deadlock_con1;
2592--echo # Reap SELECT.
2593reap;
2594
2595--echo #
2596--echo # Now a more complex scenario involving two connections
2597--echo # waiting for MDL and one for TDC.
2598--echo #
2599set debug_sync= 'RESET';
2600
2601connection deadlock_con1;
2602--echo # Start a statement which will acquire SR metadata lock on t2, open it
2603--echo # and then stop, before trying to acquire SR on t1 and opening it.
2604set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2605--echo # Sending:
2606send select * from t2, t1;
2607
2608connection deadlock_con2;
2609--echo # Wait till the above SELECT stops.
2610set debug_sync='now WAIT_FOR parked';
2611--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2612--echo # SNW locks on t2 and wait till SELECT closes t2.
2613--echo # Sending:
2614send flush tables t2 with read lock;
2615
2616connection deadlock_con3;
2617--echo # Wait until FLUSH TABLES WITH READ LOCK starts waiting
2618--echo # for SELECT to close t2.
2619let $wait_condition=
2620  select count(*) = 1 from information_schema.processlist
2621  where state = "Waiting for table flush" and
2622        info = "flush tables t2 with read lock";
2623--source include/wait_condition.inc
2624
2625--echo # The below DROP TABLES should acquire X lock on t1 and start
2626--echo # waiting for X lock on t2.
2627--echo # Sending:
2628send drop tables t1, t2;
2629
2630connection default;
2631--echo # Wait until DROP TABLES starts waiting for X lock on t2.
2632let $wait_condition=
2633  select count(*) = 1 from information_schema.processlist
2634  where state = "Waiting for table metadata lock" and
2635        info = "drop tables t1, t2";
2636--source include/wait_condition.inc
2637
2638--echo # Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
2639--echo # creating a deadlock. This deadlock should be detected and resolved
2640--echo # by backing-off SELECT. As a result, FTWRL should be able to finish.
2641set debug_sync='now SIGNAL go';
2642
2643connection deadlock_con2;
2644--echo # Reap FLUSH TABLES WITH READ LOCK.
2645reap;
2646--echo # Unblock DROP TABLES.
2647unlock tables;
2648
2649connection deadlock_con3;
2650--echo # Reap DROP TABLES.
2651reap;
2652
2653connection deadlock_con1;
2654--echo # Reap SELECT. It should emit error about missing table.
2655--error ER_NO_SUCH_TABLE
2656reap;
2657
2658connection default;
2659
2660set debug_sync= 'RESET';
2661
2662disconnect deadlock_con1;
2663disconnect deadlock_con2;
2664disconnect deadlock_con3;
2665
2666
2667--echo #
2668--echo # Test for a scenario in which FLUSH TABLES <list> WITH READ LOCK
2669--echo # used to erroneously release metadata locks.
2670--echo #
2671connect(con1,localhost,root,,);
2672connect(con2,localhost,root,,);
2673connection default;
2674--disable_warnings
2675drop tables if exists t1, t2;
2676--enable_warnings
2677set debug_sync= 'RESET';
2678create table t1(i int);
2679create table t2(j int);
2680
2681connection con2;
2682set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2683
2684--echo # The below FLUSH TABLES <list> WITH READ LOCK should acquire
2685--echo # SNW locks on t1 and t2, open table t1 and block on the debug
2686--echo # sync point.
2687--echo # Sending:
2688send flush tables t1, t2 with read lock;
2689
2690connection con1;
2691--echo # Wait till FLUSH TABLES <list> WITH READ LOCK stops.
2692set debug_sync='now WAIT_FOR parked';
2693
2694# Simple flush tables should not block
2695flush tables;
2696
2697--echo # Start a statement which will flush all tables and thus
2698--echo # invalidate table t1 open by FLUSH TABLES <list> WITH READ LOCK.
2699--echo # Sending:
2700send flush tables t1;
2701
2702connection default;
2703--echo # Wait till the above FLUSH TABLES blocks.
2704let $wait_condition=
2705  select count(*) = 1 from information_schema.processlist
2706  where state = "Waiting for table metadata lock" and
2707        info = "flush tables t1";
2708--source include/wait_condition.inc
2709
2710--echo # Resume FLUSH TABLES <list> WITH READ LOCK, so it tries to open t2
2711--echo # discovers that its t1 is obsolete and tries to reopen all tables.
2712--echo # Such reopen should not cause releasing of SNW metadata locks
2713--echo # which would result in assertion failures.
2714set debug_sync='now SIGNAL go';
2715
2716connection con2;
2717--echo # Reap FLUSH TABLES <list> WITH READ LOCK.
2718reap;
2719unlock tables;
2720
2721connection con1;
2722--echo # Reap FLUSH TABLES.
2723reap;
2724
2725--echo # Clean-up.
2726connection default;
2727drop tables t1, t2;
2728set debug_sync= 'RESET';
2729disconnect con1;
2730disconnect con2;
2731
2732
2733--echo #
2734--echo # Test for bug #46748 "Assertion in MDL_context::wait_for_locks()
2735--echo # on INSERT + CREATE TRIGGER".
2736--echo #
2737--disable_warnings
2738drop tables if exists t1, t2, t3, t4, t5;
2739--enable_warnings
2740--echo # Let us simulate scenario in which we open some tables from extended
2741--echo # part of prelocking set but then encounter conflicting metadata lock,
2742--echo # so have to back-off and wait for it to go away.
2743connect (con1root,localhost,root,,test,,);
2744connect (con2root,localhost,root,,test,,);
2745connection default;
2746create table t1 (i int);
2747create table t2 (j int);
2748create table t3 (k int);
2749create table t4 (l int);
2750create trigger t1_bi before insert on t1 for each row
2751  insert into t2 values (new.i);
2752create trigger t2_bi before insert on t2 for each row
2753  insert into t3 values (new.j);
2754--echo #
2755connection con1root;
2756lock tables t4 read;
2757--echo #
2758connection con2root;
2759--echo # Send :
2760--send rename table t3 to t5, t4 to t3;
2761--echo #
2762connection default;
2763--echo # Wait until the above RENAME TABLE adds pending requests for exclusive
2764--echo # metadata lock on its tables and blocks due to 't4' being used by LOCK
2765--echo # TABLES.
2766let $wait_condition= select count(*)= 1 from information_schema.processlist
2767                       where state= 'Waiting for table metadata lock' and
2768                             info='rename table t3 to t5, t4 to t3';
2769--source include/wait_condition.inc
2770--echo # Send :
2771--send insert into t1 values (1);
2772--echo #
2773connection con1root;
2774--echo # Wait until INSERT statement waits due to encountering pending
2775--echo # exclusive metadata lock on 't3'.
2776let $wait_condition= select count(*)= 1 from information_schema.processlist
2777                       where state= 'Waiting for table metadata lock' and
2778                             info='insert into t1 values (1)';
2779--source include/wait_condition.inc
2780unlock tables;
2781--echo #
2782connection con2root;
2783--echo # Reap RENAME TABLE.
2784--reap
2785--echo #
2786connection default;
2787--echo # Reap INSERT.
2788--reap
2789--echo # Clean-up.
2790disconnect con1root;
2791disconnect con2root;
2792drop tables t1, t2, t3, t5;
2793
2794
2795--echo #
2796--echo # Bug#42546 - Backup: RESTORE fails, thinking it finds an existing table
2797--echo #
2798
2799--disable_warnings
2800DROP TABLE IF EXISTS t1;
2801--enable_warnings
2802set @save_log_output=@@global.log_output;
2803set global log_output=file;
2804
2805connect(con2, localhost, root,,);
2806
2807--echo #
2808--echo # Test 1: CREATE TABLE
2809--echo #
2810
2811connection con2;
2812--echo # Start insert on the not-yet existing table
2813--echo # Wait after taking the MDL lock
2814SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
2815--send INSERT INTO t1 VALUES(1,"def")
2816
2817connection default;
2818SET DEBUG_SYNC= 'now WAIT_FOR locked';
2819--echo # Now INSERT has a MDL on the non-existent table t1.
2820
2821--echo #
2822--echo # Continue the INSERT once CREATE waits for exclusive lock
2823SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
2824--echo # Try to create that table.
2825--send CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), KEY(c1))
2826
2827--echo # Insert fails
2828connection con2;
2829--error ER_NO_SUCH_TABLE
2830--reap
2831
2832connection default;
2833--reap;
2834SET DEBUG_SYNC= 'RESET';
2835SHOW TABLES;
2836
2837--disable_warnings
2838DROP TABLE IF EXISTS t1;
2839--enable_warnings
2840
2841--echo #
2842--echo # Test 2: CREATE TABLE LIKE
2843--echo #
2844
2845CREATE TABLE t2 (c1 INT, c2 VARCHAR(100), KEY(c1));
2846
2847connection con2;
2848--echo # Start insert on the not-yet existing table
2849--echo # Wait after taking the MDL
2850SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
2851--send INSERT INTO t1 VALUES(1,"def")
2852
2853connection default;
2854SET DEBUG_SYNC= 'now WAIT_FOR locked';
2855--echo # Now INSERT has a MDL on the non-existent table t1.
2856
2857--echo #
2858--echo # Continue the INSERT once CREATE waits for exclusive lock
2859SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
2860--echo # Try to create that table.
2861--send CREATE TABLE t1 LIKE t2
2862
2863--echo # Insert fails
2864connection con2;
2865--error ER_NO_SUCH_TABLE
2866--reap
2867
2868connection default;
2869--reap
2870SET DEBUG_SYNC= 'RESET';
2871SHOW TABLES;
2872
2873DROP TABLE t2;
2874disconnect con2;
2875--disable_warnings
2876DROP TABLE IF EXISTS t1;
2877--enable_warnings
2878
2879set global log_output=@save_log_output;
2880
2881
2882--echo #
2883--echo # Bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE HIGH_PRIORITY
2884--echo #             FOR UPDATE"
2885--echo #
2886--disable_warnings
2887drop tables if exists t1, t2;
2888--enable_warnings
2889connect (con46044, localhost, root,,);
2890connect (con46044_2, localhost, root,,);
2891connect (con46044_3, localhost, root,,);
2892connection default;
2893create table t1 (i int);
2894insert into t1 values(1);
2895
2896--echo # Let us check that we won't deadlock if during filling
2897--echo # of I_S table we encounter conflicting metadata lock
2898--echo # which owner is in its turn waiting for our connection.
2899lock tables t1 read;
2900
2901connection con46044_2;
2902--echo # Sending:
2903--send update t1 set i = 2
2904
2905connection con46044;
2906
2907--echo # Waiting until UPDATE t1 SET ... is blocked.
2908let $wait_condition=
2909  select count(*) = 1 from information_schema.processlist
2910  where state = "Waiting for table level lock" and
2911        info = "update t1 set i = 2";
2912--source include/wait_condition.inc
2913
2914--echo # Sending:
2915--send create table t2 select * from t1;
2916
2917connection default;
2918--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
2919let $wait_condition=
2920  select count(*) = 1 from information_schema.processlist
2921  where state = "Waiting for table level lock" and
2922        info = "create table t2 select * from t1";
2923--source include/wait_condition.inc
2924
2925--echo # First let us check that SHOW FIELDS/DESCRIBE doesn't
2926--echo # gets blocked and emits and error.
2927--error ER_WARN_I_S_SKIPPED_TABLE
2928show fields from t2;
2929
2930--echo # Now test for I_S query which reads only .FRMs.
2931--echo #
2932--echo # Query below should only emit a warning.
2933select column_name from information_schema.columns
2934  where table_schema='test' and table_name='t2';
2935
2936--echo # Finally, test for I_S query which does full-blown table open.
2937--echo #
2938--echo # Query below should not be blocked. Warning message should be
2939--echo # stored in the 'table_comment' column.
2940select table_name, table_type, auto_increment, table_comment
2941  from information_schema.tables where table_schema='test' and table_name='t2';
2942
2943connection default;
2944unlock tables;
2945
2946connection con46044;
2947--echo # Reaping CREATE TABLE ... SELECT ... .
2948--reap
2949drop table t2;
2950
2951connection con46044_2;
2952--echo # Reaping UPDATE t1 statement
2953--reap
2954
2955--echo #
2956--echo # Let us also check that queries to I_S wait for conflicting metadata
2957--echo # locks to go away instead of skipping table with a warning in cases
2958--echo # when deadlock is not possible. This is a nice thing from compatibility
2959--echo # and ease of use points of view.
2960--echo #
2961--echo # We check same three queries to I_S in this new situation.
2962
2963connection con46044_2;
2964lock tables t1 read;
2965
2966connection con46044_3;
2967--echo # Sending:
2968send update t1 set i = 3;
2969
2970connection con46044;
2971
2972--echo # Waiting until UPDATE t1 SET ... is blocked.
2973let $wait_condition=
2974  select count(*) = 1 from information_schema.processlist
2975  where state = "Waiting for table level lock" and
2976        info = "update t1 set i = 3";
2977--source include/wait_condition.inc
2978
2979--echo # Sending:
2980--send create table t2 select * from t1;
2981
2982connection default;
2983--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
2984let $wait_condition=
2985  select count(*) = 1 from information_schema.processlist
2986  where state = "Waiting for table level lock" and
2987        info = "create table t2 select * from t1";
2988--source include/wait_condition.inc
2989
2990--echo # Let us check that SHOW FIELDS/DESCRIBE gets blocked.
2991--echo # Sending:
2992--send show fields from t2;
2993
2994connection con46044_2;
2995--echo # Wait until SHOW FIELDS gets blocked.
2996let $wait_condition=
2997  select count(*) = 1 from information_schema.processlist
2998  where state = "Waiting for table metadata lock" and
2999        info = "show fields from t2";
3000--source include/wait_condition.inc
3001
3002unlock tables;
3003
3004connection con46044;
3005--echo # Reaping CREATE TABLE ... SELECT ... .
3006--reap
3007
3008connection default;
3009--echo # Reaping SHOW FIELDS ...
3010--reap
3011drop table t2;
3012
3013connection con46044_3;
3014--echo # Reaping UPDATE t1 statement
3015--reap
3016
3017connection con46044_2;
3018lock tables t1 read;
3019
3020connection con46044_3;
3021--echo # Sending:
3022--send update t1 set i = 4
3023
3024connection con46044;
3025
3026--echo # Waiting until UPDATE t1 SET ... is blocked.
3027let $wait_condition=
3028  select count(*) = 1 from information_schema.processlist
3029  where state = "Waiting for table level lock" and
3030        info = "update t1 set i = 4";
3031--source include/wait_condition.inc
3032
3033--echo # Sending:
3034--send create table t2 select * from t1;
3035
3036connection default;
3037--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
3038let $wait_condition=
3039  select count(*) = 1 from information_schema.processlist
3040  where state = "Waiting for table level lock" and
3041        info = "create table t2 select * from t1";
3042--source include/wait_condition.inc
3043
3044--echo # Check that I_S query which reads only .FRMs gets blocked.
3045--echo # Sending:
3046--send select column_name from information_schema.columns where table_schema='test' and table_name='t2';
3047
3048connection con46044_2;
3049--echo # Wait until SELECT COLUMN_NAME FROM I_S.COLUMNS  gets blocked.
3050let $wait_condition=
3051  select count(*) = 1 from information_schema.processlist
3052  where state = "Waiting for table metadata lock" and
3053        info like "select column_name from information_schema.columns%";
3054--source include/wait_condition.inc
3055
3056unlock tables;
3057
3058connection con46044;
3059--echo # Reaping CREATE TABLE ... SELECT ... .
3060--reap
3061
3062connection default;
3063--echo # Reaping SELECT COLUMN_NAME FROM I_S.COLUMNS
3064--reap
3065drop table t2;
3066
3067connection con46044_3;
3068--echo # Reaping UPDATE t1 statement
3069--reap
3070
3071connection con46044_2;
3072lock tables t1 read;
3073
3074connection con46044_3;
3075--echo # Sending:
3076--send update t1 set i = 5
3077
3078connection con46044;
3079
3080--echo # Waiting until UPDATE t1 SET ... is blocked.
3081let $wait_condition=
3082  select count(*) = 1 from information_schema.processlist
3083  where state = "Waiting for table level lock" and
3084        info = "update t1 set i = 5";
3085--source include/wait_condition.inc
3086
3087--echo # Sending:
3088--send create table t2 select * from t1;
3089
3090connection default;
3091--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
3092let $wait_condition=
3093  select count(*) = 1 from information_schema.processlist
3094  where state = "Waiting for table level lock" and
3095        info = "create table t2 select * from t1";
3096--source include/wait_condition.inc
3097
3098--echo # Finally, check that I_S query which does full-blown table open
3099--echo # also gets blocked.
3100--echo # Sending:
3101--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t2';
3102
3103connection con46044_2;
3104--echo # Wait until SELECT ... FROM I_S.TABLES gets blocked.
3105let $wait_condition=
3106  select count(*) = 1 from information_schema.processlist
3107  where state = "Waiting for table metadata lock" and
3108        info like "select table_name, table_type, auto_increment, table_comment from information_schema.tables%";
3109--source include/wait_condition.inc
3110
3111unlock tables;
3112
3113connection con46044;
3114--echo # Reaping CREATE TABLE ... SELECT ... .
3115--reap
3116
3117connection default;
3118--echo # Reaping SELECT ... FROM I_S.TABLES
3119--reap
3120drop table t2;
3121
3122connection con46044_3;
3123--echo # Reaping UPDATE t1 statement
3124--reap
3125
3126connection default;
3127--echo # Clean-up.
3128disconnect con46044;
3129disconnect con46044_2;
3130disconnect con46044_3;
3131drop table t1;
3132
3133
3134--echo #
3135--echo # Test for bug #46273 "MySQL 5.4.4 new MDL: Bug#989 is not fully fixed
3136--echo #                      in case of ALTER".
3137--echo #
3138--disable_warnings
3139drop table if exists t1;
3140--enable_warnings
3141set debug_sync= 'RESET';
3142connect (con46273,localhost,root,,test,,);
3143connection default;
3144create table t1 (c1 int primary key, c2 int, c3 int);
3145insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
3146
3147begin;
3148select * from t1 where c2 = 3;
3149
3150--echo #
3151connection con46273;
3152set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL alter_table_locked WAIT_FOR alter_go';
3153--send alter table t1 add column e int, rename to t2;
3154
3155--echo #
3156connection default;
3157set debug_sync='now WAIT_FOR alter_table_locked';
3158set debug_sync='mdl_acquire_lock_wait SIGNAL alter_go';
3159--echo # The below statement should get ER_LOCK_DEADLOCK error
3160--echo # (i.e. it should not allow ALTER to proceed, and then
3161--echo # fail due to 't1' changing its name to 't2').
3162--error ER_LOCK_DEADLOCK
3163update t1 set c3=c3+1 where c2 = 3;
3164
3165--echo #
3166connection con46273;
3167--echo # Reap ALTER TABLE.
3168--reap
3169
3170--echo #
3171connection default;
3172disconnect con46273;
3173--echo # Clean-up.
3174set debug_sync= 'RESET';
3175drop table t2;
3176
3177
3178--echo #
3179--echo # Test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
3180--echo #                      and DML".
3181--echo #
3182--disable_warnings
3183drop tables if exists t1;
3184--enable_warnings
3185connect (con46673, localhost, root,,);
3186connection default;
3187create table t1 (i int);
3188
3189connection con46673;
3190begin;
3191insert into t1 values (1);
3192
3193connection default;
3194--echo # Statement below should not get blocked. And if after some
3195--echo # changes to code it is there should not be a deadlock between
3196--echo # it and transaction from connection 'con46673'.
3197flush tables with read lock;
3198unlock tables;
3199
3200connection con46673;
3201delete from t1 where i = 1;
3202commit;
3203
3204connection default;
3205--echo # Clean-up
3206disconnect con46673;
3207drop table t1;
3208
3209
3210--echo #
3211--echo # Bug#48210 FLUSH TABLES WITH READ LOCK deadlocks
3212--echo #           against concurrent CREATE PROCEDURE
3213--echo #
3214
3215connect (con2, localhost, root);
3216
3217--echo # Test 1: CREATE PROCEDURE
3218
3219connection default;
3220--echo # Start CREATE PROCEDURE and open mysql.proc
3221SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
3222--send CREATE PROCEDURE p1() SELECT 1
3223
3224connection con2;
3225SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3226--echo # Check that FLUSH must wait to get the GRL
3227--echo # and let CREATE PROCEDURE continue
3228SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
3229--send FLUSH TABLES WITH READ LOCK
3230
3231connection default;
3232--reap
3233
3234connection con2;
3235--reap
3236UNLOCK TABLES;
3237
3238connection default;
3239SET DEBUG_SYNC= 'RESET';
3240
3241--echo # Test 2: DROP PROCEDURE
3242
3243connection default;
3244--echo # Start DROP PROCEDURE and open tables
3245SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait';
3246--send DROP PROCEDURE p1
3247
3248connection con2;
3249SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3250--echo # Check that FLUSH must wait to get the GRL
3251--echo # and let DROP PROCEDURE continue
3252SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info;
3253SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
3254--send FLUSH TABLES WITH READ LOCK
3255
3256connection default;
3257--echo # Once FLUSH TABLES WITH READ LOCK starts waiting
3258--echo # DROP PROCEDURE will be waked up and will drop
3259--echo # procedure. Global read lock will be granted after
3260--echo # this statement ends.
3261--echo #
3262--echo # Reaping DROP PROCEDURE.
3263--reap
3264
3265connection con2;
3266--echo # Reaping FTWRL.
3267--reap
3268UNLOCK TABLES;
3269connection default;
3270SET DEBUG_SYNC= 'RESET';
3271
3272--echo #
3273--echo # UPDATE should wait for FTWRL with non transactional table second
3274--echo #
3275
3276create table t1 (a int) engine=myisam;
3277create table t2 (a int) engine=innodb;
3278insert into t1 values (1);
3279insert into t2 values (1);
3280
3281SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait execute 2';
3282--send update t1,t2 set t1.a=2,t2.a=3
3283
3284connection con2;
3285SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3286SET DEBUG_SYNC= 'now SIGNAL grlwait';
3287SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3288SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
3289FLUSH TABLES WITH READ LOCK;
3290
3291connection default;
3292--echo # Reaping UPDATE
3293--reap
3294
3295connection con2;
3296UNLOCK TABLES;
3297
3298connection default;
3299SET DEBUG_SYNC= 'RESET';
3300
3301# This will cause a wait as we first get lock for innodb table t2 but FTWRL
3302# will cause lock for t1 to wait
3303
3304SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait execute 2';
3305--send update t2,t1 set t1.a=2,t2.a=3
3306
3307connection con2;
3308SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3309SET DEBUG_SYNC= 'now SIGNAL grlwait';
3310SET DEBUG_SYNC= 'now WAIT_FOR table_opened';
3311SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
3312FLUSH TABLES WITH READ LOCK;
3313
3314let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.metadata_lock_info;
3315--source include/wait_condition.inc
3316SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info;
3317
3318unlock tables;
3319
3320connection default;
3321--echo # Reaping UPDATE
3322--reap
3323SET DEBUG_SYNC= 'RESET';
3324drop table t1,t2;
3325disconnect con2;
3326
3327--echo #
3328--echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
3329--echo #           failed in open_ltable()
3330--echo #
3331
3332--echo # Supress warnings written to the log file
3333call mtr.add_suppression("Wait on a lock was aborted due to a pending exclusive lock");
3334
3335connect (con1,localhost,root);
3336connect (con2,localhost,root);
3337connect (con3,localhost,root);
3338connection default;
3339
3340CREATE TABLE t1 (i INT);
3341CREATE TABLE t2 (i INT);
3342
3343SET @old_general_log= @@global.general_log;
3344SET @@global.general_log= 1;
3345
3346SET @old_log_output= @@global.log_output;
3347SET @@global.log_output= 'TABLE';
3348
3349SET @old_sql_log_off= @@session.sql_log_off;
3350SET @@session.sql_log_off= 1;
3351
3352--echo # connection: con1
3353connection con1;
3354HANDLER t1 OPEN;
3355
3356--echo # connection: con3
3357connection con3;
3358SET @@session.sql_log_off= 1;
3359
3360--echo # connection: con2
3361connection con2;
3362SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
3363
3364# The below statement will block on the debug sync point
3365# after it gets write lock on mysql.general_log table.
3366--echo # Sending:
3367--send SELECT 1
3368
3369--echo # connection: con3
3370connection con3;
3371SET DEBUG_SYNC= 'now WAIT_FOR parked';
3372
3373--echo # connection: con1
3374connection con1;
3375# This statement will block in open_ltable() when
3376# trying to write into mysql.general_log.
3377--echo # Sending:
3378--send SELECT 1
3379
3380--echo # connection: con3
3381connection con3;
3382let $wait_condition=
3383  SELECT COUNT(*) = 1 FROM information_schema.processlist
3384  WHERE state = "Waiting for table level lock" and info = "SELECT 1";
3385--source include/wait_condition.inc
3386# The ALTER below will try to abort the statement in connection con1,
3387# since the latter waits on a table-level lock while having a HANDLER
3388# open. This will cause mysql_lock_tables() in con1 fail which before
3389# triggered the assert.
3390ALTER TABLE t1 ADD COLUMN j INT;
3391
3392--echo # connection: default
3393connection default;
3394SET DEBUG_SYNC= 'now SIGNAL go';
3395
3396--echo # connection: con1
3397connection con1;
3398--echo # Reaping SELECT 1
3399--reap
3400HANDLER t1 CLOSE;
3401
3402--echo # connection: con2
3403connection con2;
3404--echo # Reaping SELECT 1
3405--reap
3406
3407--echo # connection: default
3408connection default;
3409DROP TABLE t1, t2;
3410SET DEBUG_SYNC= 'RESET';
3411disconnect con1;
3412disconnect con2;
3413disconnect con3;
3414SET @@global.general_log= @old_general_log;
3415SET @@global.log_output= @old_log_output;
3416SET @@session.sql_log_off= @old_sql_log_off;
3417
3418
3419--echo #
3420--echo # Additional coverage for bug #50913 "Deadlock between
3421--echo # open_and_lock_tables_derived and MDL". The main test
3422--echo # case is in lock_multi.test
3423--echo #
3424--disable_warnings
3425drop table if exists t1;
3426--enable_warnings
3427set debug_sync= 'RESET';
3428connect (con50913_1,localhost,root);
3429connect (con50913_2,localhost,root);
3430connection default;
3431create table t1 (i int) engine=InnoDB;
3432
3433connection con50913_1;
3434set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go';
3435--echo # Sending:
3436--send alter table t1 add column j int, ALGORITHM=COPY
3437
3438connection default;
3439--echo # Wait until ALTER TABLE gets blocked on a sync point after
3440--echo # acquiring thr_lock.c lock.
3441set debug_sync= 'now WAIT_FOR parked';
3442--echo # The below statement should wait on MDL lock and not deadlock on
3443--echo # thr_lock.c lock.
3444--echo # Sending:
3445--send truncate table t1
3446
3447connection con50913_2;
3448--echo # Wait until TRUNCATE TABLE is blocked on MDL lock.
3449let $wait_condition=
3450  select count(*) = 1 from information_schema.processlist
3451  where state = "Waiting for table metadata lock" and
3452        info = "truncate table t1";
3453--source include/wait_condition.inc
3454--echo # Unblock ALTER TABLE.
3455set debug_sync= 'now SIGNAL go';
3456
3457connection con50913_1;
3458--echo # Reaping ALTER TABLE.
3459--reap
3460
3461connection default;
3462--echo # Reaping TRUNCATE TABLE.
3463--reap
3464disconnect con50913_1;
3465disconnect con50913_2;
3466set debug_sync= 'RESET';
3467drop table t1;
3468
3469
3470--echo #
3471--echo # Test for bug #50998 "Deadlock in MDL code during test
3472--echo #                      rqg_mdl_stability".
3473--echo # Also provides coverage for the case when addition of
3474--echo # waiting statement adds several loops in the waiters
3475--echo # graph and therefore several searches for deadlock
3476--echo # should be performed.
3477--disable_warnings
3478drop table if exists t1;
3479--enable_warnings
3480set debug_sync= 'RESET';
3481connect (con1,localhost,root);
3482connect (con2,localhost,root);
3483connect (con3,localhost,root);
3484connection default;
3485create table t1 (i int);
3486
3487connection con1;
3488begin;
3489select * from t1;
3490
3491connection con2;
3492begin;
3493select * from t1;
3494
3495connection default;
3496--echo # Start ALTER TABLE which will acquire SNW lock and
3497--echo # table lock and get blocked on sync point.
3498set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go';
3499--echo # Sending:
3500--send alter table t1 add column j int
3501
3502connection con1;
3503--echo # Wait until ALTER TABLE gets blocked on a sync point.
3504set debug_sync= 'now WAIT_FOR parked';
3505--echo # Sending:
3506--send insert into t1 values (1)
3507
3508connection con2;
3509--echo # Sending:
3510--send insert into t1 values (1)
3511
3512connection con3;
3513--echo # Wait until both 'con1' and 'con2' are blocked trying to acquire
3514--echo # SW lock on the table.
3515let $wait_condition=
3516  select count(*) = 2 from information_schema.processlist
3517  where state = "Waiting for table metadata lock" and
3518        info = "insert into t1 values (1)";
3519--source include/wait_condition.inc
3520--echo # Unblock ALTER TABLE. Since it will try to upgrade SNW to X lock
3521--echo # deadlock with two loops in waiting graph will occur. Both loops
3522--echo # should be found and DML statements in both 'con1' and 'con2'
3523--echo # should be aborted with ER_LOCK_DEADLOCK errors.
3524set debug_sync= 'now SIGNAL go';
3525
3526connection con1;
3527--echo # Reaping INSERT. It should end with ER_LOCK_DEADLOCK error and
3528--echo # not wait indefinitely (as it happened before the bugfix).
3529--error ER_LOCK_DEADLOCK
3530--reap
3531commit;
3532
3533connection con2;
3534--echo # Reaping INSERT.
3535--error ER_LOCK_DEADLOCK
3536--reap
3537commit;
3538
3539connection default;
3540--echo # Reap ALTER TABLE.
3541--reap
3542
3543disconnect con1;
3544disconnect con2;
3545disconnect con3;
3546connection default;
3547set debug_sync= 'RESET';
3548drop table t1;
3549
3550--echo #
3551--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
3552--echo #
3553--echo # Ensure that a acquired lock is not given up due to a conflict.
3554--echo #
3555
3556connect (con1,localhost,root,,test,,);
3557connect (con2,localhost,root,,test,,);
3558connect (con3,localhost,root,,test,,);
3559
3560connection default;
3561
3562--disable_warnings
3563DROP TABLE IF EXISTS t1;
3564--enable_warnings
3565
3566CREATE TABLE t1 (a INT) ENGINE=InnoDB;
3567INSERT INTO t1 VALUES (1),(2),(3);
3568
3569connection con1;
3570LOCK TABLES t1 WRITE;
3571SET debug_sync='upgrade_lock_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate';
3572send TRUNCATE TABLE t1;
3573
3574connection default;
3575SET debug_sync='now WAIT_FOR parked_truncate';
3576
3577connection con2;
3578SET debug_sync='after_open_table_ignore_flush SIGNAL parked_show WAIT_FOR go_show';
3579send SHOW FIELDS FROM t1;
3580
3581connection default;
3582SET debug_sync='now WAIT_FOR parked_show';
3583
3584connection con3;
3585SET debug_sync='after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush';
3586send FLUSH TABLES t1;
3587
3588connection default;
3589SET debug_sync='now WAIT_FOR parked_flush';
3590SET debug_sync='now SIGNAL go_truncate';
3591--echo # Ensure that truncate waits for a exclusive lock
3592let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3593  WHERE state='Waiting for table metadata lock' AND info='TRUNCATE TABLE t1';
3594--source include/wait_condition.inc
3595SET debug_sync= 'now SIGNAL go_show';
3596
3597connection con1;
3598--echo # Reaping...
3599reap;
3600UNLOCK TABLES;
3601
3602connection con2;
3603--echo # Reaping...
3604reap;
3605
3606connection default;
3607SET debug_sync= 'now SIGNAL go_flush';
3608
3609connection con3;
3610--echo # Reaping...
3611reap;
3612
3613disconnect con1;
3614disconnect con2;
3615disconnect con3;
3616
3617connection default;
3618SET debug_sync= 'RESET';
3619DROP TABLE t1;
3620
3621
3622--echo #
3623--echo # Bug#52856 concurrent show columns or show full columns causes a crash!!!
3624--echo #
3625CREATE TABLE t1(a CHAR(255));
3626
3627connect(con1, localhost, root);
3628SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed";
3629--send SHOW FULL COLUMNS FROM t1
3630
3631connection default;
3632SET DEBUG_SYNC= "now WAIT_FOR waiting";
3633--replace_column 8 #
3634SHOW FULL COLUMNS FROM t1;
3635SET DEBUG_SYNC= "now SIGNAL completed";
3636--replace_column 8 #
3637connection con1;
3638--reap
3639connection default;
3640DROP TABLE t1;
3641disconnect con1;
3642
3643
3644--echo #
3645--echo # Tests for schema-scope locks
3646--echo #
3647
3648--disable_warnings
3649DROP DATABASE IF EXISTS db1;
3650DROP DATABASE IF EXISTS db2;
3651--enable_warnings
3652
3653connect (con2, localhost, root);
3654connect (con3, localhost, root);
3655
3656--echo # Test 1:
3657--echo # CREATE DATABASE blocks database DDL on the same database, but
3658--echo # not database DDL on different databases. Tests X vs X lock.
3659--echo #
3660
3661connection default;
3662SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3663--echo # Sending:
3664--send CREATE DATABASE db1
3665
3666connection con2;
3667SET DEBUG_SYNC= 'now WAIT_FOR locked';
3668--echo # Sending:
3669# This should block.
3670--send CREATE DATABASE db1
3671
3672connection con3;
3673let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3674  WHERE state='Waiting for schema metadata lock' AND info='CREATE DATABASE db1';
3675--source include/wait_condition.inc
3676# This should not block.
3677CREATE DATABASE db2;
3678ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
3679DROP DATABASE db2;
3680SET DEBUG_SYNC= 'now SIGNAL blocked';
3681
3682connection default;
3683--echo # Reaping: CREATE DATABASE db1
3684--reap
3685
3686connection con2;
3687--echo # Reaping: CREATE DATABASE db1
3688--error ER_DB_CREATE_EXISTS
3689--reap
3690
3691--echo # Test 2:
3692--echo # ALTER DATABASE blocks database DDL on the same database, but
3693--echo # not database DDL on different databases. Tests X vs X lock.
3694--echo #
3695
3696connection default;
3697SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3698--echo # Sending:
3699--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3700
3701connection con2;
3702SET DEBUG_SYNC= 'now WAIT_FOR locked';
3703--echo # Sending:
3704# This should block.
3705--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3706
3707connection con3;
3708let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3709  WHERE state='Waiting for schema metadata lock'
3710  AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
3711--source include/wait_condition.inc
3712# This should not block.
3713CREATE DATABASE db2;
3714ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
3715DROP DATABASE db2;
3716SET DEBUG_SYNC= 'now SIGNAL blocked';
3717
3718connection default;
3719--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3720--reap
3721
3722connection con2;
3723--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3724--reap
3725
3726connection default;
3727SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3728--echo # Sending:
3729--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3730
3731connection con2;
3732SET DEBUG_SYNC= 'now WAIT_FOR locked';
3733--echo # Sending:
3734# This should also block.
3735--send DROP DATABASE db1
3736
3737connection con3;
3738let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3739  WHERE state='Waiting for schema metadata lock' AND info='DROP DATABASE db1';
3740--source include/wait_condition.inc
3741SET DEBUG_SYNC= 'now SIGNAL blocked';
3742
3743connection default;
3744--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3745--reap
3746
3747connection con2;
3748--echo # Reaping: DROP DATABASE db1
3749--reap
3750# Recreate the database
3751CREATE DATABASE db1;
3752
3753--echo # Test 3:
3754--echo # Two ALTER..UPGRADE of the same database are mutually exclusive, but
3755--echo # two ALTER..UPGRADE of different databases are not. Tests X vs X lock.
3756--echo #
3757
3758let $MYSQLD_DATADIR= `select @@datadir`;
3759# Manually make a 5.0 database from the template
3760--mkdir $MYSQLD_DATADIR/a-b-c
3761--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c/db.opt
3762--mkdir $MYSQLD_DATADIR/a-b-c-d
3763--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c-d/db.opt
3764
3765connection default;
3766SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3767--echo # Sending:
3768--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
3769
3770connection con2;
3771SET DEBUG_SYNC= 'now WAIT_FOR locked';
3772--echo # Sending:
3773# This should block.
3774--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
3775
3776connection con3;
3777let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3778  WHERE state='Waiting for schema metadata lock'
3779  AND info='ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME';
3780--source include/wait_condition.inc
3781# This should not block.
3782ALTER DATABASE `#mysql50#a-b-c-d` UPGRADE DATA DIRECTORY NAME;
3783SET DEBUG_SYNC= 'now SIGNAL blocked';
3784
3785connection default;
3786--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
3787--reap
3788
3789connection con2;
3790--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
3791--error ER_BAD_DB_ERROR
3792--reap
3793DROP DATABASE `a-b-c`;
3794DROP DATABASE `a-b-c-d`;
3795
3796--echo # Test 4:
3797--echo # DROP DATABASE blocks database DDL on the same database, but
3798--echo # not database DDL on different databases. Tests X vs X lock.
3799--echo #
3800
3801connection default;
3802SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3803--echo # Sending:
3804--send DROP DATABASE db1
3805
3806connection con2;
3807SET DEBUG_SYNC= 'now WAIT_FOR locked';
3808--echo # Sending:
3809# This should block.
3810--send DROP DATABASE db1
3811
3812connection con3;
3813let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3814  WHERE state='Waiting for schema metadata lock' AND info='DROP DATABASE db1';
3815--source include/wait_condition.inc
3816# This should not block.
3817CREATE DATABASE db2;
3818ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
3819DROP DATABASE db2;
3820SET DEBUG_SYNC= 'now SIGNAL blocked';
3821
3822connection default;
3823--echo # Reaping: DROP DATABASE db1
3824--reap
3825
3826connection con2;
3827--echo # Reaping: DROP DATABASE db1
3828--error ER_DB_DROP_EXISTS
3829--reap
3830
3831connection default;
3832CREATE DATABASE db1;
3833SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3834--echo # Sending:
3835--send DROP DATABASE db1
3836
3837connection con2;
3838SET DEBUG_SYNC= 'now WAIT_FOR locked';
3839--echo # Sending:
3840# This should also block.
3841--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3842
3843connection con3;
3844let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3845  WHERE state='Waiting for schema metadata lock'
3846  AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
3847--source include/wait_condition.inc
3848SET DEBUG_SYNC= 'now SIGNAL blocked';
3849
3850connection default;
3851--echo # Reaping: DROP DATABASE db1
3852--reap
3853
3854connection con2;
3855--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
3856# Error 1 is from ALTER DATABASE when the database does not exist.
3857# Listing the error twice to prevent result diffences based on filename.
3858--error 1,1
3859--reap
3860
3861
3862--echo # Test 5:
3863--echo # Locked database name prevents CREATE of tables in that database.
3864--echo # Tests X vs IX lock.
3865--echo #
3866
3867connection default;
3868CREATE DATABASE db1;
3869SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3870--echo # Sending:
3871--send DROP DATABASE db1
3872
3873connection con2;
3874SET DEBUG_SYNC= 'now WAIT_FOR locked';
3875--echo # Sending:
3876# This should block.
3877--send CREATE TABLE db1.t1 (a INT)
3878
3879connection con3;
3880let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3881  WHERE state='Waiting for schema metadata lock' AND
3882        info='CREATE TABLE db1.t1 (a INT)';
3883--source include/wait_condition.inc
3884SET DEBUG_SYNC= 'now SIGNAL blocked';
3885
3886connection default;
3887--echo # Reaping: DROP DATABASE db1
3888--reap
3889
3890connection con2;
3891--echo # Reaping: CREATE TABLE db1.t1 (a INT)
3892--error ER_BAD_DB_ERROR
3893--reap
3894
3895--echo # Test 6:
3896--echo # Locked database name prevents RENAME of tables to/from that database.
3897--echo # Tests X vs IX lock.
3898--echo #
3899
3900connection default;
3901CREATE DATABASE db1;
3902CREATE TABLE db1.t1 (a INT);
3903SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3904--echo # Sending:
3905--send DROP DATABASE db1
3906
3907connection con2;
3908SET DEBUG_SYNC= 'now WAIT_FOR locked';
3909--echo # Sending:
3910# This should block.
3911--send RENAME TABLE db1.t1 TO test.t1
3912
3913connection con3;
3914let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3915  WHERE state='Waiting for schema metadata lock' AND
3916        info='RENAME TABLE db1.t1 TO test.t1';
3917--source include/wait_condition.inc
3918SET DEBUG_SYNC= 'now SIGNAL blocked';
3919
3920connection default;
3921--echo # Reaping: DROP DATABASE db1
3922--reap
3923
3924connection con2;
3925--echo # Reaping: RENAME TABLE db1.t1 TO test.t1
3926--error ER_NO_SUCH_TABLE
3927--reap
3928
3929connection default;
3930CREATE DATABASE db1;
3931CREATE TABLE test.t2 (a INT);
3932SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3933--echo # Sending:
3934--send DROP DATABASE db1
3935
3936connection con2;
3937SET DEBUG_SYNC= 'now WAIT_FOR locked';
3938--echo # Sending:
3939# This should block.
3940--send RENAME TABLE test.t2 TO db1.t2
3941
3942connection con3;
3943let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3944  WHERE state='Waiting for schema metadata lock' AND
3945        info='RENAME TABLE test.t2 TO db1.t2';
3946--source include/wait_condition.inc
3947SET DEBUG_SYNC= 'now SIGNAL blocked';
3948
3949connection default;
3950--echo # Reaping: DROP DATABASE db1
3951--reap
3952
3953connection con2;
3954--echo # Reaping: RENAME TABLE test.t2 TO db1.t2
3955# Error 7 is from RENAME TABLE where the target database does not exist.
3956# Listing the error twice to prevent result diffences based on filename.
3957--error 7, 7
3958--reap
3959DROP TABLE test.t2;
3960
3961
3962--echo # Test 7:
3963--echo # Locked database name prevents DROP of tables in that database.
3964--echo # Tests X vs IX lock.
3965--echo #
3966
3967connection default;
3968CREATE DATABASE db1;
3969CREATE TABLE db1.t1 (a INT);
3970SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
3971--echo # Sending:
3972--send DROP DATABASE db1
3973
3974connection con2;
3975SET DEBUG_SYNC= 'now WAIT_FOR locked';
3976--echo # Sending:
3977# This should block.
3978--send DROP TABLE db1.t1
3979
3980connection con3;
3981let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
3982  WHERE state='Waiting for schema metadata lock' AND info='DROP TABLE db1.t1';
3983--source include/wait_condition.inc
3984SET DEBUG_SYNC= 'now SIGNAL blocked';
3985
3986connection default;
3987--echo # Reaping: DROP DATABASE db1
3988--reap
3989
3990connection con2;
3991--echo # Reaping: DROP TABLE db1.t1
3992--error ER_BAD_TABLE_ERROR
3993--reap
3994
3995connection default;
3996disconnect con2;
3997disconnect con3;
3998SET DEBUG_SYNC= 'RESET';
3999
4000--echo #
4001--echo # End of tests for schema-scope locks
4002--echo #
4003
4004--echo #
4005--echo # Tests of granted global S lock (FLUSH TABLE WITH READ LOCK)
4006--echo #
4007
4008CREATE DATABASE db1;
4009CREATE TABLE db1.t1(a INT);
4010connect(con2, localhost, root);
4011connect(con3, localhost, root);
4012
4013connection default;
4014FLUSH TABLE WITH READ LOCK;
4015
4016connection con2;
4017# IX global lock should block
4018--send CREATE TABLE db1.t2(a INT)
4019
4020connection default;
4021let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
4022  WHERE state='Waiting for backup lock'
4023  AND info='CREATE TABLE db1.t2(a INT)';
4024--source include/wait_condition.inc
4025UNLOCK TABLES;
4026
4027connection con2;
4028--echo # Reaping CREATE TABLE db1.t2(a INT)
4029--reap
4030
4031connection default;
4032FLUSH TABLE WITH READ LOCK;
4033
4034connection con2;
4035# X global lock should block
4036--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
4037
4038connection default;
4039let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
4040  WHERE state='Waiting for backup lock'
4041  AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
4042--source include/wait_condition.inc
4043UNLOCK TABLES;
4044
4045connection con2;
4046--echo # Reaping ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
4047--reap
4048
4049connection default;
4050FLUSH TABLE WITH READ LOCK;
4051
4052connection con2;
4053# S global lock should not block
4054FLUSH TABLE WITH READ LOCK;
4055UNLOCK TABLES;
4056
4057connection default;
4058UNLOCK TABLES;
4059DROP DATABASE db1;
4060disconnect con2;
4061disconnect con3;
4062
4063
4064--echo #
4065--echo # Bug#56292 Deadlock with ALTER TABLE and MERGE tables
4066--echo #
4067
4068--disable_warnings
4069DROP TABLE IF EXISTS t1, t2, m1;
4070--enable_warnings
4071
4072CREATE TABLE t1(a INT) engine=MyISAM;
4073CREATE TABLE t2(a INT) engine=MyISAM;
4074CREATE TABLE m1(a INT) engine=MERGE UNION=(t1, t2);
4075
4076INSERT INTO t1 VALUES (1), (2);
4077INSERT INTO t2 VALUES (3), (4);
4078
4079connect(con1, localhost, root);
4080connect(con2, localhost, root);
4081connect(con3, localhost, root);
4082
4083connection con1;
4084--echo # We need EXECUTE 2 since ALTER TABLE does SU => SNW => X and we want
4085--echo # to stop at the second upgrade.
4086SET DEBUG_SYNC= 'mdl_upgrade_lock SIGNAL upgrade WAIT_FOR continue EXECUTE 2';
4087--echo # Sending:
4088--send ALTER TABLE m1 engine=MERGE UNION=(t2, t1)
4089
4090connection con2;
4091--echo # Waiting for ALTER TABLE to try lock upgrade
4092SET DEBUG_SYNC= 'now WAIT_FOR upgrade';
4093SET DEBUG_SYNC= 'now SIGNAL continue';
4094SET DEBUG_SYNC= 'now WAIT_FOR upgrade';
4095--echo # Sending:
4096--send DELETE FROM t2 WHERE a = 3
4097
4098connection con3;
4099--echo # Check that DELETE is waiting on a metadata lock and not a table lock.
4100let $wait_condition=
4101  SELECT COUNT(*) = 1 FROM information_schema.processlist
4102  WHERE state = "Waiting for table metadata lock" AND
4103        info = "DELETE FROM t2 WHERE a = 3";
4104--source include/wait_condition.inc
4105--echo # Now that DELETE blocks on a metadata lock, we should be able to do
4106--echo # SELECT * FROM m1 here. SELECT used to be blocked by a DELETE table
4107--echo # lock request.
4108--send SELECT * FROM m1 WHERE a < 3
4109
4110connection default;
4111--echo # Resuming ALTER TABLE
4112SET DEBUG_SYNC= 'now SIGNAL continue';
4113
4114connection con1;
4115--echo # Reaping: ALTER TABLE m1 engine=MERGE UNION=(t2, t1)
4116--reap
4117connection con2;
4118--echo # Reaping: DELETE FROM t2 WHERE a = 3
4119--reap
4120connection con3;
4121--echo # Reaping: SELECT * FROM m1 WHERE a < 3
4122--reap
4123connection default;
4124DROP TABLE m1, t1, t2;
4125SET DEBUG_SYNC= 'RESET';
4126disconnect con1;
4127disconnect con2;
4128disconnect con3;
4129
4130
4131--echo #
4132--echo # MDEV-12620 - set lock_wait_timeout = 1;flush tables with read lock;
4133--echo #              lock not released after timeout
4134--echo #
4135
4136CREATE TABLE t1(a INT) ENGINE=InnoDB;
4137SET debug_sync='open_tables_after_open_and_process_table SIGNAL ready WAIT_FOR go';
4138send INSERT INTO t1 values (1);
4139
4140connect (con1,localhost,root,,);
4141SET debug_sync='now WAIT_FOR ready';
4142# lock_wait_timeout should be 0 in 10.3, so that we don't have to wait at all
4143SET lock_wait_timeout=1;
4144--error ER_LOCK_WAIT_TIMEOUT
4145FLUSH TABLES WITH READ LOCK;
4146SET debug_sync='now SIGNAL go';
4147
4148connection default;
4149reap;
4150
4151--echo # After MDEV-5536, SELECT will not block FLUSH TABLES
4152
4153SET debug_sync='RESET';
4154SET debug_sync='open_tables_after_open_and_process_table SIGNAL ready WAIT_FOR go';
4155send SELECT * FROM t1;
4156
4157connection con1;
4158SET debug_sync='now WAIT_FOR ready';
4159# lock_wait_timeout should be 0 in 10.3, so that we don't have to wait at all
4160SET lock_wait_timeout=1;
4161FLUSH TABLES WITH READ LOCK;
4162SET debug_sync='now SIGNAL go';
4163
4164connection default;
4165reap;
4166connection con1;
4167unlock tables;
4168connection default;
4169
4170SET debug_sync='RESET';
4171DROP TABLE t1;
4172
4173disconnect con1;
4174
4175# Check that all connections opened by test cases in this file are really
4176# gone so execution of other tests won't be affected by their presence.
4177--source include/wait_until_count_sessions.inc
4178