File: alter_table-big_myisam.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (384 lines) | stat: -rw-r--r-- 12,708 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#
# Tests for various concurrency-related aspects of ALTER TABLE implemetation
# Note: MyISAM specific test

# Start the server with MyISAM as default storage engine
--source include/force_myisam_default.inc
# Test need MyISAM to support disable key feature
--source include/have_myisam.inc
# This test takes rather long time so let us run it only in --big-test mode
--source include/big_test.inc
# We are using some debug-only features in this test
--source include/have_debug.inc
# Also we are using SBR to check that statements are executed
# in proper order.
--source include/force_binlog_format_statement.inc

--source include/count_sessions.inc

--echo #
--echo # 1.5) ALTER TABLE RENAME which fails at the late stage for SEs
--echo #      supporting and not supporting atomic DDL.
--echo #
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
CREATE TABLE t2 (i INT) ENGINE=MyISAM;
LOCK TABLES t1 WRITE, t2 WRITE;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t1 RENAME TO t3;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE supporting atomic DDL table still should be available under
--echo # old name.
SELECT * FROM t1;

--connect (con1, localhost, root,,)
SET @old_lock_wait_timeout= @@lock_wait_timeout;
connection con1;
--echo # New name should not be locked.
--error ER_NO_SUCH_TABLE
SELECT * FROM t3;

connection default;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t2 RENAME TO t4;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE not supporting atomic DDL table will be
--echo # removed from list of locked tables. And new
--echo # name should not be added.
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t2;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t4;

connection con1;
--echo # But metadata lock on old name can be still kept.
# Disable prepared statements, since for them the below check
# works differently. The prepare phase of statements execution
# acquires weaker S metadata lock (which do not conflict with
# SNRW locks held by LOCK TABLE WRITE) and manages to discover
# that table with such name doesn't exist.
--disable_ps_protocol
SET @@lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t2;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
--enable_ps_protocol
--echo # New name should not be locked.
SELECT * FROM t4;

connection default;
UNLOCK TABLES;
DROP TABLES t1, t4;


--echo #
--echo # 2.5) ALTER TABLE INPLACE with RENAME clause fails at the late stage
--echo #      for SEs supporting and not supporting atomic DDL.
--echo #
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
CREATE TABLE t2 (i INT) ENGINE=MyISAM;
LOCK TABLES t1 WRITE, t2 WRITE;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t1 ADD COLUMN j INT, RENAME TO t3, ALGORITHM=INPLACE;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE supporting atomic DDL table still should be available under
--echo # old name.
SELECT * FROM t1;

connection con1;
--echo # New name should not be locked.
--error ER_NO_SUCH_TABLE
SELECT * FROM t3;

connection default;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t2 RENAME COLUMN i TO j, RENAME TO t4, ALGORITHM=INPLACE;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE not supporting atomic DDL table will be
--echo # removed from list of locked tables. And new
--echo # name should not be added.
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t2;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t4;

connection con1;
--echo # But metadata lock on old name can be still kept.
# Disable prepared statements, since for them the below check
# works differently. The prepare phase of statements execution
# acquires weaker S metadata lock (which do not conflict with
# SNRW locks held by LOCK TABLE WRITE) and manages to discover
# that table with such name doesn't exist.
--disable_ps_protocol
SET @@lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t2;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
--enable_ps_protocol
--echo # New name should not be locked.
SELECT * FROM t4;

connection default;
UNLOCK TABLES;
DROP TABLES t1, t4;

--echo #
--echo # 3.5) ALTER TABLE COPY with RENAME clause fails at the late stage
--echo #      for SEs supporting and not supporting atomic DDL.
--echo #
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
CREATE TABLE t2 (i INT) ENGINE=MyISAM;
CREATE DATABASE mysqltest;
LOCK TABLES t1 WRITE, t2 WRITE;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t1 ADD COLUMN j INT, RENAME TO t3, ALGORITHM=COPY;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE supporting atomic DDL table still should be available under
--echo # old name.
SELECT * FROM t1;

connection con1;
--echo # New name should not be locked.
--error ER_NO_SUCH_TABLE
SELECT * FROM t3;

connection default;
DROP TABLE t1;

SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t2 RENAME COLUMN i TO j, RENAME TO t4, ALGORITHM=COPY;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE not supporting atomic DDL table will be
--echo # removed from list of locked tables. And new
--echo # name should not be added.
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t2;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t4;

connection con1;
--echo # Metadata locks on both old and new names are still kept.
# Disable prepared statements, since for them the below check
# works differently. The prepare phase of statements execution
# acquires weaker S metadata locks (which do not conflict with
# SNRW locks held by LOCK TABLE WRITE) and manages to discover
# that tables with such names don't exist.
--disable_ps_protocol
SET @@lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t2;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t4;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
--enable_ps_protocol

connection default;
UNLOCK TABLES;

--echo # Now test SE not supporting atomic DDL and different schema
--echo # to improve code coverage.
connection default;
LOCK TABLE t4 WRITE;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t4 RENAME COLUMN j TO i, RENAME TO mysqltest.t4, ALGORITHM=COPY;
SET @@debug='-d,injecting_fault_writing';
--echo # For SE not supporting atomic DDL table will be
--echo # removed from list of locked tables. And new
--echo # name should not be added.
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t4;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM mysqltest.t4;

connection con1;
--echo # Metadata locks on both old and new names are still kept.
# Disable prepared statements, since for them the below check
# works differently. The prepare phase of statements execution
# acquires weaker S metadata locks (which do not conflict with
# SNRW locks held by LOCK TABLE WRITE) and manages to discover
# that tables with such names don't exist.
--disable_ps_protocol
SET @@lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t4;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM mysqltest.t4;
--echo # Also IX lock on new schema should be kept.
--error ER_LOCK_WAIT_TIMEOUT
ALTER DATABASE mysqltest CHARACTER SET latin1;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
--enable_ps_protocol

connection default;
UNLOCK TABLES;
DROP DATABASE mysqltest;

--echo #
--echo # 3.6) Special case ALTER TABLE COPY with RENAME clause which
--echo #      non-atomic, adds foreign keys and fails at the late stage.
--echo #
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2 (fk INT) ENGINE=MyISAM;
LOCK TABLES t2 WRITE, t1 WRITE;
SET @@debug='+d,injecting_fault_writing';
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
ALTER TABLE t2 ADD FOREIGN KEY (fk) REFERENCES t1(pk), ENGINE=InnoDB, RENAME TO t3, ALGORITHM=COPY;
SET @@debug='-d,injecting_fault_writing';
--echo # Table should be removed from locked tables list and new
--echo # table name should not be added.
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t2;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t3;

connection con1;
--echo # However, metadata locks on both old and new names are still kept.
# Disable prepared statements, since for them the below check
# works differently. The prepare phase of statements execution
# acquires weaker S metadata locks (which do not conflict with
# SNRW locks held by LOCK TABLE WRITE) and manages to discover
# that tables with such names don't exist.
--disable_ps_protocol
SET @@lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t2;
--error ER_LOCK_WAIT_TIMEOUT
SELECT * FROM t3;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
--enable_ps_protocol

connection default;
--echo # And delete from parent table is possible and doesn't cause asserts.
DELETE FROM t1;
UNLOCK TABLES;
DROP TABLES t3, t1;

connection con1;
disconnect con1;
--source include/wait_until_disconnected.inc
connection default;

--disable_connect_log
--echo #
--echo # Bug#24786075   FIND A WAY TO LIST #SQL... TABLE LEFT IN      
--echo #                DATA DICTIONARY IN CASE ALTER FAILS.
--echo # Test that we can see hidden temporary tables using ALTER TABLE.
--echo # Test that we can delete the hidden temporary tables that were
--echo # left by ALTER TABLE table failures in rare situations.
--echo #

CREATE TABLE t1(a INT) ENGINE=MyISAM;

SET debug="+d,exit_after_alter_table_before_rename";
--error ER_UNKNOWN_ERROR
ALTER TABLE t1 modify column a varchar(30);
SET debug="-d,exit_after_alter_table_before_rename";

--echo # Verify that #sql... tables are not seen by I_S and SHOW
SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
  WHERE TABLE_SCHEMA='test' AND TABLE_NAME like '#sql%';
SHOW TABLES FROM test;

--echo # The SHOW EXTENDED [FULL] syntax should show the hidden table.
--replace_regex /#sql.*$/#sql-xxxxx/
SHOW EXTENDED TABLES FROM test;

--replace_regex /#sql.*$/#sql-xxxxx/
SHOW EXTENDED FULL TABLES FROM test;

--echo # Dropping the temporary table.
let $value=
  query_get_value(SHOW EXTENDED TABLES FROM test, Tables_in_test, 1);
let $stmt = DROP TABLE `$value`;
--replace_regex /#sql.*$/#sql-xxxxx/
eval $stmt;

--echo # Verify that the temporary table is dropped.
--replace_regex /#sql.*$/#sql-xxxxx/
SHOW EXTENDED TABLES FROM test;

--replace_regex /#sql.*$/#sql-xxxxx/
SHOW EXTENDED FULL TABLES FROM test;

--echo # clean-up
DROP TABLE t1;

#
# Test for Bug#25044 ALTER TABLE ... ENABLE KEYS acquires global
#                    'opening tables' lock
#
# ALTER TABLE ... ENABLE KEYS should not acquire LOCK_open mutex for
# the whole its duration as it prevents other queries from execution.
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
set debug_sync='RESET';

connect (addconroot, localhost, root,,);
connect (addconroot2, localhost, root,,);
connection default;
create table t1 (n1 int, n2 int, n3 int,
                key (n1, n2, n3),
                key (n2, n3, n1),
                key (n3, n1, n2));
create table t2 (i int) engine=innodb;

alter table t1 disable keys;
insert into t1 values (1, 2, 3);

# Later we use binlog to check the order in which statements are
# executed so let us reset it first.
reset master;
set debug_sync='alter_table_enable_indexes SIGNAL parked WAIT_FOR go';
--send alter table t1 enable keys;
connection addconroot;
# Wait until ALTER TABLE acquires metadata lock.
set debug_sync='now WAIT_FOR parked';
# This statement should not be blocked by in-flight ALTER and therefore
# should be executed and written to binlog before ALTER TABLE ... ENABLE KEYS
# finishes.
insert into t2 values (1);
# And this should wait until the end of ALTER TABLE ... ENABLE KEYS.
--send insert into t1 values (1, 1, 1);
connection addconroot2;
# Wait until the above INSERT INTO t1 is blocked due to ALTER
let $wait_condition=
    select count(*) = 1 from information_schema.processlist
    where state = "Waiting for table metadata lock" and
          info = "insert into t1 values (1, 1, 1)";
--source include/wait_condition.inc
# Resume ALTER execution.
set debug_sync='now SIGNAL go';
connection default;
--reap
connection addconroot;
--reap
connection default;
# Check that statements were executed/binlogged in correct order.
source include/show_binlog_events.inc;

# Clean up
drop tables t1, t2;
disconnect addconroot;
disconnect addconroot2;
set debug_sync='RESET';

--source include/restore_default_binlog_format.inc

# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc