MDEV-19044 Alter table corrupts while applying the modification log

Problem:
========
- InnoDB reads the length of the variable length field wrongly
while applying the modification log of instant table.

Solution:
========
rec_init_offsets_comp_ordinary(): For the temporary instant
file record, InnoDB should read the length of the variable length
field from the record itself.
parent 1b37cb71
......@@ -180,28 +180,5 @@ t3 CREATE TABLE `t3` (
UNIQUE KEY `v2` (`v2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1,t2,t3;
db.opt
#
# MDEV-26198 Assertion `0' failed in row_log_table_apply_op during
# ADD PRIMARY KEY or OPTIMIZE TABLE
#
CREATE TABLE t1(f1 year default null, f2 year default null,
f3 text, f4 year default null, f5 year default null,
f6 year default null, f7 year default null,
f8 year default null)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1);
ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE;
set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish";
ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ADD COLUMN f10 YEAR DEFAULT NULL, ALGORITHM=INPLACE;
connect con1,localhost,root,,,;
SET DEBUG_SYNC="now WAIT_FOR con1_insert";
INSERT IGNORE INTO t1 (f3) VALUES ( 'b' );
INSERT IGNORE INTO t1 (f3) VALUES ( 'l' );
SET DEBUG_SYNC="now SIGNAL con1_finish";
connection default;
disconnect con1;
SET DEBUG_SYNC=RESET;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
db.opt
@@ -470,4 +470,4 @@
--- mysql-test/suite/innodb/r/instant_alter_debug.result 2024-02-27 12:22:59.612941388 +0530
+++ mysql-test/suite/innodb/r/instant_alter_debug,dynamic.reject 2024-02-27 12:23:09.924938462 +0530
@@ -537,5 +537,5 @@
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
-33
+32
-35
+34
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
......@@ -479,14 +479,63 @@ SET DEBUG_SYNC="now WAIT_FOR try_insert";
INSERT INTO t1 VALUES(1, 2);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET DEBUG_SYNC="now SIGNAL alter_progress";
disconnect con1;
connection default;
DROP TABLE t1;
#
# MDEV-26198 Assertion `0' failed in row_log_table_apply_op during
# ADD PRIMARY KEY or OPTIMIZE TABLE
#
CREATE TABLE t1(f1 year default null, f2 year default null,
f3 text, f4 year default null, f5 year default null,
f6 year default null, f7 year default null,
f8 year default null)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1);
ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE;
set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish";
ALTER TABLE t1 ADD COLUMN f10 YEAR DEFAULT NULL, FORCE, ALGORITHM=INPLACE;
connection con1;
SET DEBUG_SYNC="now WAIT_FOR con1_insert";
INSERT IGNORE INTO t1 (f3) VALUES ( 'b' );
INSERT IGNORE INTO t1 (f3) VALUES ( 'l' );
SET DEBUG_SYNC="now SIGNAL con1_finish";
connection default;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
#
# MDEV-19044 Alter table corrupts while applying the
# modification log
#
CREATE TABLE t1 (
f1 INT,
f2 INT,
f3 char(19) CHARACTER SET utf8mb3,
f4 VARCHAR(500),
f5 TEXT)ENGINE=InnoDB;
INSERT INTO t1 VALUES(3, 1, REPEAT('a', 2), REPEAT("b", 20),'a');
ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL, ALGORITHM=INSTANT;
INSERT INTO t1 VALUES(1, 2, REPEAT('InnoDB', 2),
REPEAT("MariaDB", 20), REPEAT('a', 8000), 12);
INSERT INTO t1 VALUES(1, 2, REPEAT('MYSQL', 2),
REPEAT("MariaDB", 20), REPEAT('a', 8000), 12);
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL con1_begin WAIT_FOR con1_update';
ALTER TABLE t1 MODIFY COLUMN f2 INT NOT NULL, FORCE, ALGORITHM=INPLACE;
connection con1;
SET DEBUG_SYNC='now WAIT_FOR con1_begin';
UPDATE t1 SET f2=204 order by f1 limit 2;
SET DEBUG_SYNC='now SIGNAL con1_update';
connection default;
disconnect con1;
SET DEBUG_SYNC=reset;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
# End of 10.4 tests
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
33
35
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
......@@ -202,32 +202,6 @@ SHOW CREATE TABLE t1;
SHOW CREATE TABLE t2;
SHOW CREATE TABLE t3;
DROP TABLE t1,t2,t3;
SET DEBUG_SYNC=RESET;
--remove_files_wildcard $MYSQLD_DATADIR/test #sql*.frm
--list_files $MYSQLD_DATADIR/test
--echo #
--echo # MDEV-26198 Assertion `0' failed in row_log_table_apply_op during
--echo # ADD PRIMARY KEY or OPTIMIZE TABLE
--echo #
CREATE TABLE t1(f1 year default null, f2 year default null,
f3 text, f4 year default null, f5 year default null,
f6 year default null, f7 year default null,
f8 year default null)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1);
ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE;
set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish";
send ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ADD COLUMN f10 YEAR DEFAULT NULL, ALGORITHM=INPLACE;
connect(con1,localhost,root,,,);
SET DEBUG_SYNC="now WAIT_FOR con1_insert";
INSERT IGNORE INTO t1 (f3) VALUES ( 'b' );
INSERT IGNORE INTO t1 (f3) VALUES ( 'l' );
SET DEBUG_SYNC="now SIGNAL con1_finish";
connection default;
reap;
disconnect con1;
SET DEBUG_SYNC=RESET;
CHECK TABLE t1;
DROP TABLE t1;
......@@ -549,16 +549,67 @@ SET DEBUG_SYNC="now WAIT_FOR try_insert";
--error ER_LOCK_WAIT_TIMEOUT
INSERT INTO t1 VALUES(1, 2);
SET DEBUG_SYNC="now SIGNAL alter_progress";
disconnect con1;
connection default;
reap;
DROP TABLE t1;
--echo #
--echo # MDEV-26198 Assertion `0' failed in row_log_table_apply_op during
--echo # ADD PRIMARY KEY or OPTIMIZE TABLE
--echo #
CREATE TABLE t1(f1 year default null, f2 year default null,
f3 text, f4 year default null, f5 year default null,
f6 year default null, f7 year default null,
f8 year default null)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1);
ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE;
set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish";
send ALTER TABLE t1 ADD COLUMN f10 YEAR DEFAULT NULL, FORCE, ALGORITHM=INPLACE;
connection con1;
SET DEBUG_SYNC="now WAIT_FOR con1_insert";
INSERT IGNORE INTO t1 (f3) VALUES ( 'b' );
INSERT IGNORE INTO t1 (f3) VALUES ( 'l' );
SET DEBUG_SYNC="now SIGNAL con1_finish";
connection default;
reap;
CHECK TABLE t1;
DROP TABLE t1;
--echo #
--echo # MDEV-19044 Alter table corrupts while applying the
--echo # modification log
--echo #
CREATE TABLE t1 (
f1 INT,
f2 INT,
f3 char(19) CHARACTER SET utf8mb3,
f4 VARCHAR(500),
f5 TEXT)ENGINE=InnoDB;
INSERT INTO t1 VALUES(3, 1, REPEAT('a', 2), REPEAT("b", 20),'a');
ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL, ALGORITHM=INSTANT;
INSERT INTO t1 VALUES(1, 2, REPEAT('InnoDB', 2),
REPEAT("MariaDB", 20), REPEAT('a', 8000), 12);
INSERT INTO t1 VALUES(1, 2, REPEAT('MYSQL', 2),
REPEAT("MariaDB", 20), REPEAT('a', 8000), 12);
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL con1_begin WAIT_FOR con1_update';
send ALTER TABLE t1 MODIFY COLUMN f2 INT NOT NULL, FORCE, ALGORITHM=INPLACE;
connection con1;
SET DEBUG_SYNC='now WAIT_FOR con1_begin';
UPDATE t1 SET f2=204 order by f1 limit 2;
SET DEBUG_SYNC='now SIGNAL con1_update';
connection default;
reap;
disconnect con1;
SET DEBUG_SYNC=reset;
CHECK TABLE t1;
DROP TABLE t1;
--echo # End of 10.4 tests
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
......@@ -421,7 +421,7 @@ rec_init_offsets_comp_ordinary(
}
if (!field->fixed_len
|| (format == REC_LEAF_TEMP
|| (format <= REC_LEAF_TEMP_INSTANT
&& !dict_col_get_fixed_size(col, true))) {
/* Variable-length field: read the length */
len = *lens--;
......
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