diff options
-rw-r--r-- | mysql-test/suite/innodb/r/instant_alter_bugs.result | 18 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter_bugs.test | 20 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 4 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 2 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 2 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.cc | 2 |
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)); |