Skip to content

Commit fdb37d0

Browse files
MDEV-21787 Alter table failure tries to access uninitialized column
- Problem is that failure of inplace DDL tries to access the uninitialized column. This is caused by MDEV-19606 (commit 0274ab1). Fix is that InnoDB should use column while freeing the index when index is completely initialized.
1 parent 3ad1af9 commit fdb37d0

File tree

6 files changed

+57
-13
lines changed

6 files changed

+57
-13
lines changed
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
--- instant_alter_limit.result
2-
+++ instant_alter_limit.result
3-
@@ -42,5 +42,5 @@
1+
--- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530
2+
+++ instant_alter_limit,32k.reject 2020-05-26 19:59:19.743877366 +0530
3+
@@ -43,5 +43,12 @@
44
FROM information_schema.global_status
55
WHERE variable_name = 'innodb_instant_alter_column';
66
instants
77
-502
88
+506
99
DROP TABLE t;
10+
+#
11+
+# MDEV-21787 Alter table failure tries to access uninitialized column
12+
+#
13+
+CREATE TABLE t1(f1 INT PRIMARY KEY, f2 TEXT GENERATED ALWAYS AS (SUBSTR(f4, 1, 400)), f3 VARCHAR(500), f4 TEXT)ENGINE=InnoDB ROW_FORMAT=Compact;
14+
+ALTER TABLE t1 ADD UNIQUE KEY (f2(9));
15+
+ALTER TABLE t1 ADD COLUMN f5 TEXT, ALGORITHM=INPLACE;
16+
+DROP TABLE t1;

mysql-test/suite/innodb/r/instant_alter_limit,4k.rdiff

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
--- instant_alter_limit.result
2-
+++ instant_alter_limit.result
1+
--- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530
2+
+++ instant_alter_limit,4k.reject 2020-05-26 20:17:53.314736548 +0530
33
@@ -5,6 +5,276 @@
44
ENGINE=InnoDB;
55
INSERT INTO t VALUES(1,2,3,4,5);
@@ -295,10 +295,19 @@
295295
ALTER TABLE t ADD COLUMN b INT NOT NULL, ALGORITHM=INSTANT;
296296
ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE
297297
SELECT variable_value-@old_instant instants
298-
@@ -43,5 +319,5 @@
298+
@@ -43,5 +319,14 @@
299299
FROM information_schema.global_status
300300
WHERE variable_name = 'innodb_instant_alter_column';
301301
instants
302302
-502
303303
+474
304304
DROP TABLE t;
305+
+#
306+
+# MDEV-21787 Alter table failure tries to access uninitialized column
307+
+#
308+
+CREATE TABLE t1(f1 INT PRIMARY KEY, f2 TEXT GENERATED ALWAYS AS (SUBSTR(f4, 1, 400)), f3 VARCHAR(500), f4 TEXT)ENGINE=InnoDB ROW_FORMAT=Compact;
309+
+ALTER TABLE t1 ADD UNIQUE KEY (f2(9));
310+
+ALTER TABLE t1 ADD COLUMN f5 TEXT, ALGORITHM=INPLACE;
311+
+Warnings:
312+
+Warning 139 Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
313+
+DROP TABLE t1;
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
--- instant_alter_limit.result
2-
+++ instant_alter_limit.result
3-
@@ -42,5 +42,5 @@
1+
--- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530
2+
+++ instant_alter_limit,64k.reject 2020-05-26 20:00:22.499711222 +0530
3+
@@ -43,5 +43,12 @@
44
FROM information_schema.global_status
55
WHERE variable_name = 'innodb_instant_alter_column';
66
instants
77
-502
88
+506
99
DROP TABLE t;
10+
+#
11+
+# MDEV-21787 Alter table failure tries to access uninitialized column
12+
+#
13+
+CREATE TABLE t1(f1 INT PRIMARY KEY, f2 TEXT GENERATED ALWAYS AS (SUBSTR(f4, 1, 400)), f3 VARCHAR(500), f4 TEXT)ENGINE=InnoDB ROW_FORMAT=Compact;
14+
+ALTER TABLE t1 ADD UNIQUE KEY (f2(9));
15+
+ALTER TABLE t1 ADD COLUMN f5 TEXT, ALGORITHM=INPLACE;
16+
+DROP TABLE t1;

mysql-test/suite/innodb/r/instant_alter_limit,8k.rdiff

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
--- instant_alter_limit.result
2-
+++ instant_alter_limit.result
1+
--- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530
2+
+++ instant_alter_limit,8k.reject 2020-05-26 20:19:50.881869095 +0530
33
@@ -5,6 +5,28 @@
44
ENGINE=InnoDB;
55
INSERT INTO t VALUES(1,2,3,4,5);
@@ -47,10 +47,17 @@
4747
ALTER TABLE t ADD COLUMN b INT NOT NULL, ALGORITHM=INSTANT;
4848
ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE
4949
SELECT variable_value-@old_instant instants
50-
@@ -43,5 +71,5 @@
50+
@@ -43,5 +71,12 @@
5151
FROM information_schema.global_status
5252
WHERE variable_name = 'innodb_instant_alter_column';
5353
instants
5454
-502
5555
+492
5656
DROP TABLE t;
57+
+#
58+
+# MDEV-21787 Alter table failure tries to access uninitialized column
59+
+#
60+
+CREATE TABLE t1(f1 INT PRIMARY KEY, f2 TEXT GENERATED ALWAYS AS (SUBSTR(f4, 1, 400)), f3 VARCHAR(500), f4 TEXT)ENGINE=InnoDB ROW_FORMAT=Compact;
61+
+ALTER TABLE t1 ADD UNIQUE KEY (f2(9));
62+
+ALTER TABLE t1 ADD COLUMN f5 TEXT, ALGORITHM=INPLACE;
63+
+DROP TABLE t1;

mysql-test/suite/innodb/t/instant_alter_limit.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,17 @@ FROM information_schema.global_status
6060
WHERE variable_name = 'innodb_instant_alter_column';
6161

6262
DROP TABLE t;
63+
64+
--echo #
65+
--echo # MDEV-21787 Alter table failure tries to access uninitialized column
66+
--echo #
67+
CREATE TABLE t1(f1 INT PRIMARY KEY, f2 TEXT GENERATED ALWAYS AS (SUBSTR(f4, 1, 400)), f3 VARCHAR(500), f4 TEXT)ENGINE=InnoDB ROW_FORMAT=Compact;
68+
ALTER TABLE t1 ADD UNIQUE KEY (f2(9));
69+
let $error_code = 0;
70+
let $innodb_page_size = `SELECT @@INNODB_PAGE_SIZE`;
71+
if ($innodb_page_size == 4k) {
72+
let $error_code= ER_TOO_BIG_ROWSIZE;
73+
}
74+
--error $error_code
75+
ALTER TABLE t1 ADD COLUMN f5 TEXT, ALGORITHM=INPLACE;
76+
DROP TABLE t1;

storage/innobase/include/dict0mem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ struct dict_index_t {
12031203
@param whether to reset fields[].col */
12041204
void detach_columns(bool clear= false)
12051205
{
1206-
if (!has_virtual())
1206+
if (!has_virtual() || !cached)
12071207
return;
12081208
for (unsigned i= 0; i < n_fields; i++)
12091209
{

0 commit comments

Comments
 (0)