1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-16131 Assertion failed in dict_index_t::instant_field_value()

During a table-rebuilding online ALTER TABLE, if
dict_index_t::remove_instant() was invoked on the source table
(because it became empty), we would inadvertently change the way
how log records are written and parsed. We must keep the online_log
format unchanged throughout the whole table-rebuilding operation.

dict_col_t::def_t: Name the type of dict_col_t::def_val.

rec_get_n_add_field_len(), rec_set_n_add_field(): Define globally,
because these will be needed in row_log_table_low().

rec_init_offsets_temp(), rec_init_offsets_comp_ordinary(): Add
the parameter def_val for explicitly passing the default values
of the instantly added columns of the source table, so that
dict_index_t::instant_field_value() will not be called during
row_log_table_apply(). This allows us to consistently parse the
online_log records, even if the source table was converted
to the canonical non-instant format during the rebuild operation.

row_log_t::non_core_fields[]: The default values of the
instantly added columns on the source table; copied
during ha_innobase::prepare_inplace_alter_table()
while the table is exclusively locked.

row_log_t::instant_field_value(): Accessor to non_core_fields[],
analogous to dict_index_t::instant_field_value().

row_log_table_low(): Add fake_extra_size bytes to the record
header if the source table was converted to the canonical format
during the operation.

row_log_allocate(): Initialize row_log_t::non_core_fields.
This commit is contained in:
Marko Mäkelä
2018-07-26 22:52:53 +03:00
parent a97c190d95
commit 255328d393
6 changed files with 187 additions and 47 deletions

View File

@ -175,10 +175,42 @@ SET DEBUG_SYNC='now WAIT_FOR copied';
BEGIN;
INSERT INTO t1 SET b=1;
ROLLBACK;
disconnect stop_purge;
connection stop_purge;
COMMIT;
connection default;
InnoDB 2 transactions not purged
SET DEBUG_SYNC='now SIGNAL logged';
disconnect ddl;
connection ddl;
connection default;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
#
# MDEV-16131 Assertion failed in dict_index_t::instant_field_value()
#
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 SET a=0;
ALTER TABLE t1 ADD COLUMN b INT NOT NULL DEFAULT 2, ADD COLUMN c INT;
connection stop_purge;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1;
connection ddl;
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged';
ALTER TABLE t1 FORCE;
disconnect stop_purge;
connection default;
SET DEBUG_SYNC = 'now WAIT_FOR copied';
InnoDB 1 transactions not purged
INSERT INTO t1 SET a=1;
INSERT INTO t1 SET a=2,b=3,c=4;
SET DEBUG_SYNC = 'now SIGNAL logged';
connection ddl;
disconnect ddl;
connection default;
SET DEBUG_SYNC = RESET;
SELECT * FROM t1;
a b c
1 2 NULL
2 3 4
DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;