Commit 9fdb8c59 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-17721: Corrupted data dictionary after instant DROP COLUMN

dict_index_t::clear_instant_alter(): Remove a loop that became
redundant in commit ae2004c6
and caused corruption of n_nullable when dropping the last column
which was not declared NOT NULL.
parent 1ee0144d
...@@ -553,6 +553,11 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT; ...@@ -553,6 +553,11 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1; DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4; ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 DROP f2, ADD COLUMN f4 INT;
ALTER TABLE t1 DROP f4;
ALTER TABLE t1 DROP f1;
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1052,6 +1057,11 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT; ...@@ -1052,6 +1057,11 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1; DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4; ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 DROP f2, ADD COLUMN f4 INT;
ALTER TABLE t1 DROP f4;
ALTER TABLE t1 DROP f1;
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1551,10 +1561,15 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT; ...@@ -1551,10 +1561,15 @@ ALTER TABLE t1 DROP f1, DROP f2, ADD f4 INT, ADD f5 INT;
DELETE FROM t1; DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4; ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DROP f2, ADD COLUMN f4 INT;
ALTER TABLE t1 DROP f4;
ALTER TABLE t1 DROP f1;
DROP TABLE t1;
disconnect analyze; disconnect analyze;
SELECT variable_value-@old_instant instants SELECT variable_value-@old_instant instants
FROM information_schema.global_status FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column'; WHERE variable_name = 'innodb_instant_alter_column';
instants instants
102 111
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
...@@ -431,6 +431,12 @@ DELETE FROM t1; ...@@ -431,6 +431,12 @@ DELETE FROM t1;
ALTER TABLE t1 DROP COLUMN f4; ALTER TABLE t1 DROP COLUMN f4;
DROP TABLE t1; DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT) $engine;
ALTER TABLE t1 DROP f2, ADD COLUMN f4 INT;
ALTER TABLE t1 DROP f4;
ALTER TABLE t1 DROP f1;
DROP TABLE t1;
dec $format; dec $format;
} }
disconnect analyze; disconnect analyze;
......
...@@ -2151,7 +2151,6 @@ inline void dict_index_t::clear_instant_alter() ...@@ -2151,7 +2151,6 @@ inline void dict_index_t::clear_instant_alter()
#endif #endif
dict_field_t* const begin = &fields[first_user_field()]; dict_field_t* const begin = &fields[first_user_field()];
dict_field_t* end = &fields[n_fields]; dict_field_t* end = &fields[n_fields];
while (end[-1].col->is_dropped()) end--;
for (dict_field_t* d = begin; d < end; ) { for (dict_field_t* d = begin; d < end; ) {
/* Move fields for dropped columns to the end. */ /* Move fields for dropped columns to the end. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment