diff options
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter.result | 29 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter.test | 12 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 8 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 11 |
4 files changed, 50 insertions, 10 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index b5e82ccaefe..f25e1de904d 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -578,6 +578,15 @@ id f 1 NULL 2 NULL DROP TABLE t1; +CREATE TABLE t1(f INT, k INT NOT NULL AUTO_INCREMENT, KEY(k)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +CREATE TABLE t1(pk INT PRIMARY KEY, f INT, k INT AUTO_INCREMENT, KEY(k)) +ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 (pk) VALUES (1); +DROP TABLE t1; CREATE TABLE t1 ( pk INT PRIMARY KEY, f1 INT, @@ -1153,6 +1162,15 @@ id f 1 NULL 2 NULL DROP TABLE t1; +CREATE TABLE t1(f INT, k INT NOT NULL AUTO_INCREMENT, KEY(k)) ENGINE=InnoDB ROW_FORMAT=COMPACT; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +CREATE TABLE t1(pk INT PRIMARY KEY, f INT, k INT AUTO_INCREMENT, KEY(k)) +ENGINE=InnoDB ROW_FORMAT=COMPACT; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 (pk) VALUES (1); +DROP TABLE t1; CREATE TABLE t1 ( pk INT PRIMARY KEY, f1 INT, @@ -1728,6 +1746,15 @@ id f 1 NULL 2 NULL DROP TABLE t1; +CREATE TABLE t1(f INT, k INT NOT NULL AUTO_INCREMENT, KEY(k)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +CREATE TABLE t1(pk INT PRIMARY KEY, f INT, k INT AUTO_INCREMENT, KEY(k)) +ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 (pk) VALUES (1); +DROP TABLE t1; CREATE TABLE t1 ( pk INT PRIMARY KEY, f1 INT, @@ -1784,5 +1811,5 @@ SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -125 +131 SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index 449e154058a..273c9540606 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -447,6 +447,18 @@ ALTER TABLE t1 ADD COLUMN id INT NOT NULL AUTO_INCREMENT FIRST, ADD KEY(id); SELECT * FROM t1; DROP TABLE t1; +# MDEV-18076/MDEV-18077 Crash on AUTO_INCREMENT column after instant DROP +eval CREATE TABLE t1(f INT, k INT NOT NULL AUTO_INCREMENT, KEY(k)) $engine; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 VALUES (1); +DROP TABLE t1; + +eval CREATE TABLE t1(pk INT PRIMARY KEY, f INT, k INT AUTO_INCREMENT, KEY(k)) +$engine; +ALTER TABLE t1 DROP COLUMN f; +INSERT INTO t1 (pk) VALUES (1); +DROP TABLE t1; + # MDEV-17763 Assertion `len == 20U' failed in rec_convert_dtuple_to_rec_comp # upon DROP COLUMN eval CREATE TABLE t1 ( diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 74c554ca76a..62425d1085d 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -10294,14 +10294,6 @@ commit_cache_norebuild( f->fixed_len); } } - - DBUG_ASSERT(!ctx->instant_table->persistent_autoinc - || ctx->new_table->persistent_autoinc - == ctx->instant_table->persistent_autoinc); - - if (!ctx->instant_table->persistent_autoinc) { - ctx->new_table->persistent_autoinc = 0; - } } } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index f0e0c19e500..3b59a351112 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2218,6 +2218,9 @@ inline void dict_index_t::clear_instant_alter() DBUG_ASSERT(!fields[i].col->is_nullable()); } #endif + const dict_col_t* ai_col = table->persistent_autoinc + ? fields[table->persistent_autoinc - 1].col + : NULL; dict_field_t* const begin = &fields[first_user_field()]; dict_field_t* end = &fields[n_fields]; @@ -2238,8 +2241,14 @@ inline void dict_index_t::clear_instant_alter() n_core_fields = n_fields = n_def = end - fields; n_core_null_bytes = UT_BITS_IN_BYTES(n_nullable); std::sort(begin, end, [](const dict_field_t& a, const dict_field_t& b) - { return a.col->ind < b.col->ind; }); + { return a.col->ind < b.col->ind; }); table->instant = NULL; + if (ai_col) { + auto a = std::find_if(begin, end, + [ai_col](const dict_field_t& f) + { return f.col == ai_col; }); + table->persistent_autoinc = (a == end) ? 0 : 1 + (a - fields); + } } /** @return whether the column was instantly dropped |