Commit 3aa618a9 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-13820 trx_id_check() fails during row_log_table_apply()

When logging ROW_T_INSERT or ROW_T_UPDATE records, we did not normalize
the DB_TRX_ID of the current transaction into 0 if the current transaction
had started (modifying other tables) before the ALTER TABLE started.

MDEV-13654 introduced this normalization for ROW_T_DELETE
and for all operations with ADD PRIMARY KEY, in row_log_table_get_pk().
parent 4ea5b126
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
connect con1,localhost,root,,test;
BEGIN;
INSERT INTO t0 SET pk=1;
connect con2,localhost,root,,test;
BEGIN;
INSERT INTO t0 SET pk=2;
connection default;
SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL prepared WAIT_FOR logged';
ALTER TABLE t1 FORCE;
connection con1;
SET DEBUG_SYNC='now WAIT_FOR prepared';
INSERT INTO t1 SET pk=1;
COMMIT;
disconnect con1;
connection con2;
UPDATE t1 SET b=1;
DELETE FROM t1;
ROLLBACK;
SET DEBUG_SYNC='now SIGNAL logged';
disconnect con2;
connection default;
SET DEBUG_SYNC='RESET';
DROP TABLE t0,t1;
--source innodb_default_row_format.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
--connect (con1,localhost,root,,test)
BEGIN;
INSERT INTO t0 SET pk=1;
--connect (con2,localhost,root,,test)
BEGIN;
INSERT INTO t0 SET pk=2;
--connection default
SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL prepared WAIT_FOR logged';
send ALTER TABLE t1 FORCE;
--connection con1
SET DEBUG_SYNC='now WAIT_FOR prepared';
INSERT INTO t1 SET pk=1;
COMMIT;
--disconnect con1
--connection con2
UPDATE t1 SET b=1;
DELETE FROM t1;
ROLLBACK;
SET DEBUG_SYNC='now SIGNAL logged';
--disconnect con2
--connection default
reap;
SET DEBUG_SYNC='RESET';
DROP TABLE t0,t1;
[redundant]
innodb_default_row_format=redundant
[dynamic]
innodb_default_row_format=dynamic
# See also innodb_default_row_format.combinations
--source include/have_innodb.inc
......@@ -853,6 +853,18 @@ row_log_table_low_redundant(
}
}
dfield_t* db_trx_id = dtuple_get_nth_field(tuple, index->n_uniq);
ut_ad(dfield_get_len(db_trx_id) == DATA_TRX_ID_LEN);
ut_ad(dfield_get_len(db_trx_id + 1) == DATA_ROLL_PTR_LEN);
if (trx_read_trx_id(static_cast<const byte*>
(dfield_get_data(db_trx_id)))
< index->online_log->min_trx) {
dfield_set_data(db_trx_id, reset_trx_id, DATA_TRX_ID_LEN);
dfield_set_data(db_trx_id + 1, reset_trx_id + DATA_TRX_ID_LEN,
DATA_ROLL_PTR_LEN);
}
rec_comp_status_t status = index->is_instant()
? REC_STATUS_COLUMNS_ADDED : REC_STATUS_ORDINARY;
......@@ -1057,7 +1069,16 @@ row_log_table_low(
memcpy(b, rec - rec_extra_size - omit_size, rec_extra_size);
b += rec_extra_size;
ulint len;
ulint trx_id_offs = rec_get_nth_field_offs(
offsets, index->n_uniq, &len);
ut_ad(len == DATA_TRX_ID_LEN);
memcpy(b, rec, rec_offs_data_size(offsets));
if (trx_read_trx_id(b + trx_id_offs)
< index->online_log->min_trx) {
memcpy(b + trx_id_offs,
reset_trx_id, sizeof reset_trx_id);
}
b += rec_offs_data_size(offsets);
row_log_table_close(index, b, mrec_size, avail_size);
......
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