Commit 43c20542 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-19030: Assertion failed in rec_init_offsets() after DROP COLUMN

This basically is a duplicate of MDEV-18219, proving that the
assertion was not relaxed correctly.

dict_index_t::in_instant_init: A debug flag that will only be set in
btr_cur_instant_init_low() in order to suppress the assertion failure
in rec_init_offsets() for that code path only.
parent 51748696
......@@ -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;
......@@ -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;
......@@ -423,8 +423,12 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
}
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;
......
......@@ -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 */
......
......@@ -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
......
......@@ -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));
......
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