summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_bugs.result18
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test20
-rw-r--r--storage/innobase/btr/btr0cur.cc4
-rw-r--r--storage/innobase/dict/dict0load.cc2
-rw-r--r--storage/innobase/include/dict0mem.h2
-rw-r--r--storage/innobase/rem/rem0rec.cc2
6 files changed, 47 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result
index 5284d021c67..1633f11bfac 100644
--- a/mysql-test/suite/innodb/r/instant_alter_bugs.result
+++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result
@@ -175,3 +175,21 @@ INSERT INTO t1 SELECT * FROM t1;
ALTER TABLE t1 DROP a;
ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
DROP TABLE t1;
+#
+# MDEV-19030 Assertion index->n_core_null_bytes <= ... failed
+# in rec_init_offsets after instant DROP COLUMN
+#
+CREATE TABLE t1 (a INT, b INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES (),(),(),();
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+ALTER TABLE t1 FORCE;
+INSERT INTO t1 SELECT * FROM t1;
+ALTER TABLE t1 DROP a, ADD a SMALLINT NOT NULL;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index 7b7ba44f09b..d05baf1a097 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -185,3 +185,23 @@ ALTER TABLE t1 DROP a;
# Exploit MDEV-17468 to force the table definition to be reloaded
ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-19030 Assertion index->n_core_null_bytes <= ... failed
+--echo # in rec_init_offsets after instant DROP COLUMN
+--echo #
+CREATE TABLE t1 (a INT, b INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES (),(),(),();
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+ALTER TABLE t1 FORCE;
+INSERT INTO t1 SELECT * FROM t1;
+ALTER TABLE t1 DROP a, ADD a SMALLINT NOT NULL;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+# Exploit MDEV-17468 to force the table definition to be reloaded
+ALTER TABLE t1 ADD vb INT AS (b) VIRTUAL;
+DROP TABLE t1;
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 434f5392cfa..ba72d795e92 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -423,8 +423,12 @@ unreadable:
}
btr_cur_t cur;
+ /* Relax the assertion in rec_init_offsets(). */
+ ut_ad(!index->in_instant_init);
+ ut_d(index->in_instant_init = true);
dberr_t err = btr_cur_open_at_index_side(true, index, BTR_SEARCH_LEAF,
&cur, 0, mtr);
+ ut_d(index->in_instant_init = false);
if (err != DB_SUCCESS) {
index->table->corrupted = true;
return err;
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 1540f7e53bc..fe1628caac5 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -426,6 +426,8 @@ dict_process_sys_indexes_rec(
const char* err_msg;
byte* buf;
+ ut_d(index->is_dummy = true);
+ ut_d(index->in_instant_init = false);
buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
/* Parse the record, and get "dict_index_t" struct filled */
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 8a8530867ca..858cc82b1fd 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -964,6 +964,8 @@ struct dict_index_t {
#ifdef UNIV_DEBUG
/** whether this is a dummy index object */
bool is_dummy;
+ /** whether btr_cur_instant_init() is in progress */
+ bool in_instant_init;
uint32_t magic_n;/*!< magic number */
/** Value of dict_index_t::magic_n */
# define DICT_INDEX_MAGIC_N 76789786
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index c76bf3429b9..2f6c1c0cca8 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -618,7 +618,7 @@ rec_init_offsets(
until btr_cur_instant_init_low() has invoked
dict_table_t::deserialise_columns(). */
ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable)
- || (!leaf && index->n_core_fields != index->n_fields));
+ || index->in_instant_init);
ut_d(offsets[2] = ulint(rec));
ut_d(offsets[3] = ulint(index));