diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-04 18:10:31 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2019-12-05 08:54:14 +0100 |
commit | c4ed1bee5b0dcaf878080d2bdc193f7d28cff78b (patch) | |
tree | 8387431e67e7f486a859ae0f30017db3a03e4828 | |
parent | 008ee867a4cc80e079bd2a8b7f8c8543d80c31f1 (diff) | |
download | mariadb-git-c4ed1bee5b0dcaf878080d2bdc193f7d28cff78b.tar.gz |
MDEV-21172 Memory leak after failed ADD PRIMARY KEY
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter,4k.rdiff | 60 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter.result | 23 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter_bugs.result | 1 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter.test | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter_bugs.test | 2 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 3 |
6 files changed, 78 insertions, 23 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter,4k.rdiff b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff index c362174e5ba..cb65d12b09f 100644 --- a/mysql-test/suite/innodb/r/instant_alter,4k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter,4k.rdiff @@ -119,7 +119,16 @@ connection default; InnoDB 0 transactions not purged DROP TABLE t1,t2,t3,t4,big; -@@ -698,7 +712,7 @@ +@@ -515,6 +529,8 @@ + CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; + ALTER TABLE t1 ADD d TEXT; + ALTER TABLE t1 ADD PRIMARY KEY (a,b); ++Warnings: ++Warning 139 Row size too large (> 1979). 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. + ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; + DROP TABLE t1; + CREATE TABLE t1 +@@ -703,7 +719,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -128,7 +137,7 @@ connection default; ROLLBACK; connection analyze; -@@ -708,7 +722,7 @@ +@@ -713,7 +729,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -137,7 +146,7 @@ connection default; BEGIN; UPDATE t2 SET d1 = repeat(id, 200); -@@ -719,7 +733,7 @@ +@@ -724,7 +740,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -146,7 +155,7 @@ connection default; ROLLBACK; connection analyze; -@@ -729,7 +743,7 @@ +@@ -734,7 +750,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -155,7 +164,7 @@ connection default; ALTER TABLE t2 DROP p; affected rows: 0 -@@ -778,7 +792,9 @@ +@@ -783,7 +799,9 @@ info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE t3 ADD COLUMN b BLOB NOT NULL; affected rows: 0 @@ -166,7 +175,7 @@ INSERT INTO t3 SET id=4; ERROR HY000: Field 'c2' doesn't have a default value INSERT INTO t3 SET id=4, c2=0, b=0xf09f98b1; -@@ -791,7 +807,9 @@ +@@ -796,7 +814,9 @@ ALTER TABLE t3 CHANGE t phrase TEXT DEFAULT 0xc3a4c3a448, CHANGE b b BLOB NOT NULL DEFAULT 'binary line of business'; affected rows: 4 @@ -177,7 +186,7 @@ INSERT INTO t3 SET id=5, c2=9; Warnings: Note 1265 Data truncated for column 'c7' at row 1 -@@ -805,7 +823,9 @@ +@@ -810,7 +830,9 @@ 5 9 POLYGON((1 1,2 2,3 3,1 1)) 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 03:00:42 1970-01-01 ääH binary line of business ALTER TABLE t3 DROP c3, DROP c7; affected rows: 0 @@ -188,7 +197,7 @@ SELECT * FROM t3; id c2 c4 c5 c6 c8 phrase b 1 1 1970-01-01 03:00:42 1970-01-01 03:00:42 NULL 1970-01-01 The quick brown fox jumps over the lazy dog -@@ -833,6 +853,8 @@ +@@ -838,6 +860,8 @@ (id INT PRIMARY KEY, c1 VARCHAR(4000), c2 VARCHAR(4000), c3 VARCHAR(1000), p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'), SPATIAL INDEX(p)) ENGINE=InnoDB ROW_FORMAT=COMPACT; @@ -197,7 +206,7 @@ BEGIN; INSERT INTO big SET id=1, c1=REPEAT('a', 200), c2=REPEAT('b', 200), c3=REPEAT('c', 159); -@@ -850,13 +872,15 @@ +@@ -855,13 +879,15 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -215,7 +224,7 @@ CHECKSUM TABLE big; Table Checksum test.big 1705165209 -@@ -873,7 +897,7 @@ +@@ -878,7 +904,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -224,7 +233,7 @@ connection default; ROLLBACK; CHECKSUM TABLE big; -@@ -886,7 +910,7 @@ +@@ -891,7 +917,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -233,7 +242,16 @@ connection default; InnoDB 0 transactions not purged DROP TABLE t1,t2,t3,t4,big; -@@ -1155,7 +1179,7 @@ +@@ -977,6 +1003,8 @@ + CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) ENGINE=InnoDB ROW_FORMAT=COMPACT; + ALTER TABLE t1 ADD d TEXT; + ALTER TABLE t1 ADD PRIMARY KEY (a,b); ++Warnings: ++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. + ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; + DROP TABLE t1; + CREATE TABLE t1 +@@ -1165,7 +1193,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -242,7 +260,7 @@ connection default; ROLLBACK; connection analyze; -@@ -1165,7 +1189,7 @@ +@@ -1175,7 +1203,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -251,7 +269,7 @@ connection default; BEGIN; UPDATE t2 SET d1 = repeat(id, 200); -@@ -1176,7 +1200,7 @@ +@@ -1186,7 +1214,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -260,7 +278,7 @@ connection default; ROLLBACK; connection analyze; -@@ -1186,7 +1210,7 @@ +@@ -1196,7 +1224,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t2'; clust_index_size @@ -269,7 +287,7 @@ connection default; ALTER TABLE t2 DROP p; affected rows: 0 -@@ -1307,7 +1331,7 @@ +@@ -1317,7 +1345,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -278,7 +296,7 @@ connection default; ALTER TABLE big ADD COLUMN (d1 INT DEFAULT 0, d2 VARCHAR(20) DEFAULT 'abcde', -@@ -1330,7 +1354,7 @@ +@@ -1340,7 +1368,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -287,7 +305,7 @@ connection default; ROLLBACK; CHECKSUM TABLE big; -@@ -1343,7 +1367,7 @@ +@@ -1353,7 +1381,7 @@ SELECT clust_index_size FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/big'; clust_index_size @@ -296,10 +314,10 @@ connection default; InnoDB 0 transactions not purged DROP TABLE t1,t2,t3,t4,big; -@@ -1431,5 +1455,5 @@ +@@ -1446,5 +1474,5 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants --54 -+55 +-57 ++58 SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index 72f6eee72b8..aadb7021887 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -512,6 +512,13 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +SET innodb_strict_mode = ON; +CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ALTER TABLE t1 ADD d TEXT; +ALTER TABLE t1 ADD PRIMARY KEY (b,a); +ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; +DROP TABLE t1; +SET innodb_strict_mode = OFF; CREATE TABLE t1 (id INT PRIMARY KEY, c2 INT UNIQUE, c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), @@ -969,6 +976,13 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +SET innodb_strict_mode = ON; +CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) ENGINE=InnoDB ROW_FORMAT=COMPACT; +ALTER TABLE t1 ADD d TEXT; +ALTER TABLE t1 ADD PRIMARY KEY (b,a); +ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; +DROP TABLE t1; +SET innodb_strict_mode = OFF; CREATE TABLE t1 (id INT PRIMARY KEY, c2 INT UNIQUE, c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), @@ -1426,10 +1440,17 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +SET innodb_strict_mode = ON; +CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 ADD d TEXT; +ALTER TABLE t1 ADD PRIMARY KEY (b,a); +ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; +DROP TABLE t1; +SET innodb_strict_mode = OFF; disconnect analyze; SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -54 +57 SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result index 9e6c537cf7e..d07067fa19f 100644 --- a/mysql-test/suite/innodb/r/instant_alter_bugs.result +++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result @@ -169,3 +169,4 @@ DROP FOREIGN KEY fk1, CHANGE b d INT UNSIGNED, ADD c INT; DROP TABLE t2, t1; +# End of 10.3 tests diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index 12d8b877d05..be79d7437c3 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -396,6 +396,18 @@ DELETE FROM t1; CHECK TABLE t1; DROP TABLE t1; +# MDEV-21172 Memory leak during ADD PRIMARY KEY + +SET innodb_strict_mode = ON; +eval CREATE TABLE t1 (a INT, b VARCHAR(500), c TEXT, UNIQUE(a,b)) $engine; +ALTER TABLE t1 ADD d TEXT; +--error 0,ER_TOO_BIG_ROWSIZE +ALTER TABLE t1 ADD PRIMARY KEY (b,a); +# Exploit MDEV-17468 to force the table definition to be reloaded +ALTER TABLE t1 ADD va INT AS (a) VIRTUAL; +DROP TABLE t1; +SET innodb_strict_mode = OFF; + dec $format; let $redundant_4k= 0; } diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test index 0edbb672584..a2626ba34a1 100644 --- a/mysql-test/suite/innodb/t/instant_alter_bugs.test +++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test @@ -169,3 +169,5 @@ ALTER TABLE t2 CHANGE b d INT UNSIGNED, ADD c INT; DROP TABLE t2, t1; + +--echo # End of 10.3 tests diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 785c8a970d4..63cb89d4e98 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5541,6 +5541,7 @@ new_table_failed: if (index) { dict_mem_index_free(index); } +error_handling_drop_uncached_1: while (++a < ctx->num_to_add_index) { dict_mem_index_free(ctx->add_index[a]); } @@ -5552,7 +5553,7 @@ new_table_failed: ctx->add_index[a] = index; if (!info.row_size_is_acceptable(*index)) { error = DB_TOO_BIG_RECORD; - goto error_handling; + goto error_handling_drop_uncached_1; } index->parser = index_defs[a].parser; index->has_new_v_col = has_new_v_col; |