~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
# Tests for various concurrency-related aspects of CREATE TABLE ... SELECT
2
# and CREATE TABLE like implementation.
3
#
4
# Note that we don't test general CREATE TABLE ... SELECT/LIKE functionality
5
# here as it is already covered by create.test. We are more interested in
6
# extreme cases.
7
#
8
# This test takes rather long time so let us run it only in --big-test mode
9
--source include/big_test.inc
10
# We are using some debug-only features in this test
11
--source include/have_debug.inc
12
# Some of tests below also use binlog to check that statements are
13
# executed and logged in correct order
14
--source include/have_binlog_format_mixed_or_statement.inc
15
16
# Create auxilliary connections
17
connect (addconroot1, localhost, root,,);
18
connect (addconroot2, localhost, root,,);
19
connect (addconroot3, localhost, root,,);
20
connection default;
21
22
--disable_warnings
23
drop table if exists t1,t2,t3,t4,t5;
24
--enable_warnings
25
26
27
#
28
# Tests for concurrency problems in CREATE TABLE ... SELECT
29
#
30
# We introduce delays between various stages of table creation
31
# and check that other statements dealing with this table cannot
32
# interfere during those delays.
33
#
34
# What happens in situation when other statement messes with
35
# table to be created before it is created ?
36
# Concurrent CREATE TABLE
37
set session debug="+d,sleep_create_select_before_create";
38
--send create table t1 select 1 as i;
39
connection addconroot1;
40
--sleep 2
41
--error ER_TABLE_EXISTS_ERROR
42
create table t1 (j char(5));
43
connection default;
44
--reap
45
show create table t1;
46
drop table t1;
47
# Concurrent CREATE TABLE ... SELECT
48
--send create table t1 select 1 as i;
49
connection addconroot1;
50
--sleep 2
51
--error ER_TABLE_EXISTS_ERROR
52
create table t1 select "Test" as j;
53
connection default;
54
--reap
55
show create table t1;
56
drop table t1;
57
# Concurrent CREATE TABLE LIKE
58
create table t3 (j char(5));
59
--send create table t1 select 1 as i;
60
connection addconroot1;
61
--sleep 2
62
--error ER_TABLE_EXISTS_ERROR
63
create table t1 like t3;
64
connection default;
65
--reap
66
show create table t1;
67
drop table t1;
68
# Concurrent RENAME TABLE
69
--send create table t1 select 1 as i;
70
connection addconroot1;
71
--sleep 2
72
--error ER_TABLE_EXISTS_ERROR
73
rename table t3 to t1;
74
connection default;
75
--reap
76
show create table t1;
77
drop table t1;
78
# Concurrent ALTER TABLE RENAME
79
--send create table t1 select 1 as i;
80
connection addconroot1;
81
--sleep 2
82
--error ER_TABLE_EXISTS_ERROR
83
alter table t3 rename to t1;
84
connection default;
85
--reap
86
show create table t1;
87
drop table t1;
88
# Concurrent ALTER TABLE RENAME which also adds column
89
--send create table t1 select 1 as i;
90
connection addconroot1;
91
--sleep 2
92
--error ER_TABLE_EXISTS_ERROR
93
alter table t3 rename to t1, add k int;
94
connection default;
95
--reap
96
show create table t1;
97
drop table t1, t3;
98
# What happens if other statement sneaks in after the table
99
# creation but before its opening ?
100
set session debug="-d,sleep_create_select_before_create:+d,sleep_create_select_before_open";
101
# Concurrent DROP TABLE
102
--send create table t1 select 1 as i;
103
connection addconroot1;
104
--sleep 2
105
drop table t1;
106
connection default;
107
--reap
108
# Concurrent RENAME TABLE
109
--send create table t1 select 1 as i;
110
connection addconroot1;
111
--sleep 2
112
rename table t1 to t2;
113
connection default;
114
--reap
115
drop table t2;
116
# Concurrent SELECT
117
--send create table t1 select 1 as i;
118
connection addconroot1;
119
--sleep 2
120
select * from t1;
121
connection default;
122
--reap
123
drop table t1;
124
# Concurrent INSERT
125
--send create table t1 select 1 as i;
126
connection addconroot1;
127
--sleep 2
128
insert into t1 values (2);
129
connection default;
130
--reap
131
select * from t1;
132
drop table t1;
133
# Concurrent CREATE TRIGGER 
134
set @a:=0;
135
--send create table t1 select 1 as i;
136
connection addconroot1;
137
--sleep 2
138
create trigger t1_bi before insert on t1 for each row set @a:=1;
139
connection default;
140
--reap
141
select @a;
142
drop table t1;
143
# Okay, now the same tests for the potential gap between open and lock
144
set session debug="-d,sleep_create_select_before_open:+d,sleep_create_select_before_lock";
145
# Concurrent DROP TABLE
146
--send create table t1 select 1 as i;
147
connection addconroot1;
148
--sleep 2
149
drop table t1;
150
connection default;
151
--reap
152
# Concurrent RENAME TABLE
153
--send create table t1 select 1 as i;
154
connection addconroot1;
155
--sleep 2
156
rename table t1 to t2;
157
connection default;
158
--reap
159
drop table t2;
160
# Concurrent SELECT
161
--send create table t1 select 1 as i;
162
connection addconroot1;
163
--sleep 2
164
select * from t1;
165
connection default;
166
--reap
167
drop table t1;
168
# Concurrent INSERT
169
--send create table t1 select 1 as i;
170
connection addconroot1;
171
--sleep 2
172
insert into t1 values (2);
173
connection default;
174
--reap
175
select * from t1;
176
drop table t1;
177
# Concurrent CREATE TRIGGER 
178
set @a:=0;
179
--send create table t1 select 1 as i;
180
connection addconroot1;
181
--sleep 2
182
create trigger t1_bi before insert on t1 for each row set @a:=1;
183
connection default;
184
--reap
185
select @a;
186
drop table t1;
187
# Some tests for case with existing table
188
set session debug="-d,sleep_create_select_before_lock:+d,sleep_create_select_before_check_if_exists";
189
create table t1 (i int);
190
# Concurrent DROP TABLE
191
--send create table if not exists t1 select 1 as i;
192
connection addconroot1;
193
--sleep 2
194
drop table t1;
195
connection default;
196
--reap
197
# Concurrent CREATE TRIGGER 
198
create table t1 (i int);
199
set @a:=0;
200
--send create table if not exists t1 select 1 as i;
201
connection addconroot1;
202
--sleep 2
203
create trigger t1_bi before insert on t1 for each row set @a:=1;
204
connection default;
205
--reap
206
select @a;
207
select * from t1;
208
drop table t1;
209
set session debug="-d,sleep_create_select_before_check_if_exists";
210
211
212
# Test for some details of CREATE TABLE ... SELECT implementation.
213
#
214
# We check that create placeholder is handled properly if we have
215
# to reopen tables in open_tables().
216
# This test heavily relies on current implementation of name-locking/
217
# table cache so it may stop working if it changes. OTOH it such problem
218
# will serve as warning that such changes should not be done lightly.
219
create table t2 (a int);
220
create table t4 (b int);
221
connection addconroot2;
222
lock table t4 write;
223
select 1;
224
connection addconroot1;
225
# Create placeholder/name-lock for t3
226
--send create table t3 as select * from t4;
227
--sleep 2
228
connection default;
229
# This statement creates placeholder for t1, then opens t2,
230
# then meets name-lock for t3 and then reopens all tables
231
--send create table t1 select * from t2, t3;
232
--sleep 2
233
connection addconroot2;
234
unlock tables;
235
connection addconroot1;
236
--reap
237
connection default;
238
--reap
239
select * from t1;
240
show create table t1;
241
drop table t1, t3;
242
# Now similar test which proves that we really temporarily
243
# remove placeholder when we reopen tables.
244
connection addconroot2;
245
lock table t4 read;
246
select 1;
247
connection addconroot1;
248
# Create name-lock for t3 
249
--send rename table t4 to t3;
250
--sleep 2
251
connection default;
252
# This statement creates placeholder for t1, then opens t2,
253
# then meets name-lock for t3 and then reopens all tables
254
--send create table if not exists t1 select 1 as i from t2, t3;
255
--sleep 2
256
connection addconroot3;
257
# We should be able to take name-lock on table t1 as we should not have
258
# open placeholder for it at this point (otherwise it is possible to
259
# come-up with situation which will lead to deadlock, e.g. think of
260
# concurrent CREATE TABLE t1 SELECT * FROM t2 and RENAME TABLE t2 TO t1)
261
create table t5 (j int);
262
# This statement takes name-lock on t1 and therefore proves 
263
# that there is no active open placeholder for it.
264
rename table t5 to t1;
265
connection addconroot2;
266
unlock tables;
267
connection addconroot1;
268
--reap
269
connection default;
270
--reap
271
select * from t1;
272
show create table t1;
273
drop table t1, t2, t3;
274
275
276
# Tests for possible concurrency issues with CREATE TABLE ... LIKE
277
#
278
# Bug #18950 "create table like does not obtain LOCK_open"
279
# Bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other
280
#             connections"
281
#
282
# Again the idea of this test is that we introduce artificial delays on
283
# various stages of table creation and check that concurrent statements
284
# for tables from CREATE TABLE ... LIKE are not interfering.
285
286
--disable_warnings
287
drop table if exists t1,t2;
288
--enable_warnings
289
290
# What happens if some statements sneak in right after we have
291
# opened source table ?
292
create table t1 (i int);
293
set session debug="+d,sleep_create_like_before_check_if_exists";
294
# Reset binlog to have clear start
295
reset master;
296
--send create table t2 like t1;
297
connection addconroot1;
298
--sleep 2
299
# DML on source table should be allowed to run concurrently
300
insert into t1 values (1);
301
# And DDL should wait
302
drop table t1;
303
connection default;
304
--reap
305
show create table t2;
306
drop table t2;
307
# Let us check that statements were executed/binlogged in correct order
308
--replace_column 2 # 5 #
309
show binlog events in 'master-bin.000001' from 106;
310
311
# Now let us check the gap between check for target table
312
# existance and copying of .frm file. 
313
create table t1 (i int);
314
set session debug="-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy";
315
# It should be impossible to create target table concurrently
316
--send create table t2 like t1;
317
connection addconroot1;
318
--sleep 2
319
create table if not exists t2 (j int);
320
connection default;
321
--reap
322
show create table t2;
323
drop table t2;
324
# And concurrent DDL on the source table should be still disallowed 
325
reset master;
326
--send create table t2 like t1;
327
connection addconroot1;
328
--sleep 2
329
drop table t1;
330
connection default;
331
--reap
332
drop table t2;
333
--replace_column 2 # 5 #
334
show binlog events in 'master-bin.000001' from 106;
335
336
# And now he gap between copying of .frm file and ha_create_table() call. 
337
create table t1 (i int);
338
set session debug="-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create";
339
# Both DML and DDL on target table should wait till operation completes
340
reset master;
341
--send create table t2 like t1;
342
connection addconroot1;
343
--sleep 2
344
insert into t2 values (1);
345
connection default;
346
--reap
347
drop table t2;
348
--send create table t2 like t1;
349
connection addconroot1;
350
--sleep 2
351
drop table t2;
352
connection default;
353
--reap
354
# Concurrent DDL on the source table still waits 
355
--send create table t2 like t1;
356
connection addconroot1;
357
--sleep 2
358
drop table t1;
359
connection default;
360
--reap
361
drop table t2;
362
--replace_column 2 # 5 #
363
show binlog events in 'master-bin.000001' from 106;
364
365
# Finally we check the gap between ha_create_table() and binlogging
366
create table t1 (i int);
367
set session debug="-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging";
368
reset master;
369
--send create table t2 like t1;
370
connection addconroot1;
371
--sleep 2
372
insert into t2 values (1);
373
connection default;
374
--reap
375
drop table t2;
376
--send create table t2 like t1;
377
connection addconroot1;
378
--sleep 2
379
drop table t2;
380
connection default;
381
--reap
382
--send create table t2 like t1;
383
connection addconroot1;
384
--sleep 2
385
drop table t1;
386
connection default;
387
--reap
388
drop table t2;
389
--replace_column 2 # 5 #
390
show binlog events in 'master-bin.000001' from 106;
391
392
set session debug="-d,sleep_create_like_before_binlogging";