summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/instant_alter.result29
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test12
-rw-r--r--storage/innobase/handler/handler0alter.cc8
-rw-r--r--storage/innobase/include/dict0mem.h11
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