Skip to content

Commit

Permalink
MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
Browse files Browse the repository at this point in the history
row_log_table_get_pk_old_col(): For replacing a NULL value for a
column of the being-added primary key, look up the correct
default value, even if columns had been instantly reordered or
dropped earlier. This ought to have been broken ever since
commit 0e5a4ac (MDEV-15562).
  • Loading branch information
dr-m committed Feb 5, 2020
1 parent a56f782 commit 2acc6f2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
24 changes: 24 additions & 0 deletions mysql-test/suite/innodb/r/instant_alter_debug.result
Expand Up @@ -343,6 +343,30 @@ UPDATE t1 SET b = 1;
SET DEBUG_SYNC='now SIGNAL update';
connection con2;
connection default;
DROP TABLE t1;
#
# MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
#
CREATE TABLE t1 (a INT, b INT, c INT, col INT) ENGINE=InnoDB;
INSERT INTO t1 () VALUES ();
ALTER TABLE t1 DROP b, DROP c, DROP col;
ALTER TABLE t1 ADD COLUMN col INT;
ALTER TABLE t1 DROP a, DROP col, ADD COLUMN b INT;
connection con2;
SET SQL_MODE= '';
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR dml';
ALTER TABLE t1 ADD PRIMARY KEY(b);
connection default;
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
UPDATE t1 SET b = 1;
SET DEBUG_SYNC = 'now SIGNAL dml';
connection con2;
Warnings:
Warning 1265 Data truncated for column 'b' at row 1
connection default;
SELECT * FROM t1;
b
1
SET DEBUG_SYNC='RESET';
disconnect con2;
DROP TABLE t1;
26 changes: 26 additions & 0 deletions mysql-test/suite/innodb/t/instant_alter_debug.test
Expand Up @@ -385,6 +385,32 @@ SET DEBUG_SYNC='now SIGNAL update';
--reap

--connection default
DROP TABLE t1;

--echo #
--echo # MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
--echo #

CREATE TABLE t1 (a INT, b INT, c INT, col INT) ENGINE=InnoDB;
INSERT INTO t1 () VALUES ();
ALTER TABLE t1 DROP b, DROP c, DROP col;
ALTER TABLE t1 ADD COLUMN col INT;
ALTER TABLE t1 DROP a, DROP col, ADD COLUMN b INT;

--connection con2
SET SQL_MODE= '';
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR dml';
send ALTER TABLE t1 ADD PRIMARY KEY(b);

--connection default
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
UPDATE t1 SET b = 1;
SET DEBUG_SYNC = 'now SIGNAL dml';
--connection con2
reap;
--connection default
SELECT * FROM t1;

SET DEBUG_SYNC='RESET';
--disconnect con2
DROP TABLE t1;
15 changes: 11 additions & 4 deletions storage/innobase/row/row0log.cc
Expand Up @@ -1137,6 +1137,7 @@ row_log_table_get_pk_old_col(
/** Maps an old table column of a PRIMARY KEY column.
@param[in] ifield clustered index field in the new table (after
ALTER TABLE)
@param[in] index the clustered index of ifield
@param[in,out] dfield clustered index tuple field in the new table
@param[in,out] heap memory heap for allocating dfield contents
@param[in] rec clustered index leaf page record in the old
Expand All @@ -1152,6 +1153,7 @@ static
dberr_t
row_log_table_get_pk_col(
const dict_field_t* ifield,
const dict_index_t* index,
dfield_t* dfield,
mem_heap_t* heap,
const rec_t* rec,
Expand All @@ -1175,14 +1177,19 @@ row_log_table_get_pk_col(
return(DB_INVALID_NULL);
}

ulint n_default_cols = i - DATA_N_SYS_COLS;
ulint new_i = dict_col_get_clust_pos(ifield->col, index);

if (UNIV_UNLIKELY(new_i >= log->defaults->n_fields)) {
ut_ad(0);
return DB_INVALID_NULL;
}

field = static_cast<const byte*>(
log->defaults->fields[n_default_cols].data);
log->defaults->fields[new_i].data);
if (!field) {
return(DB_INVALID_NULL);
}
len = log->defaults->fields[i - DATA_N_SYS_COLS].len;
len = log->defaults->fields[new_i].len;
}

if (rec_offs_nth_extern(offsets, i)) {
Expand Down Expand Up @@ -1341,7 +1348,7 @@ row_log_table_get_pk(
}

log->error = row_log_table_get_pk_col(
ifield, dfield, *heap,
ifield, new_index, dfield, *heap,
rec, offsets, i, zip_size, max_len,
log);

Expand Down

0 comments on commit 2acc6f2

Please sign in to comment.