mirror of
https://github.com/MariaDB/server.git
synced 2026-05-09 00:24:30 +02:00
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.
This commit is contained in:
parent
1b37cb71f4
commit
57cc8605eb
6 changed files with 115 additions and 61 deletions
|
|
@ -180,28 +180,5 @@ t3 CREATE TABLE `t3` (
|
||||||
UNIQUE KEY `v2` (`v2`)
|
UNIQUE KEY `v2` (`v2`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
DROP TABLE t1,t2,t3;
|
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;
|
SET DEBUG_SYNC=RESET;
|
||||||
CHECK TABLE t1;
|
db.opt
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
@@ -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
|
FROM information_schema.global_status
|
||||||
WHERE variable_name = 'innodb_instant_alter_column';
|
WHERE variable_name = 'innodb_instant_alter_column';
|
||||||
instants
|
instants
|
||||||
-33
|
-35
|
||||||
+32
|
+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);
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
SET DEBUG_SYNC="now SIGNAL alter_progress";
|
SET DEBUG_SYNC="now SIGNAL alter_progress";
|
||||||
disconnect con1;
|
|
||||||
connection default;
|
connection default;
|
||||||
DROP TABLE t1;
|
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;
|
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
|
# End of 10.4 tests
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
SELECT variable_value-@old_instant instants
|
SELECT variable_value-@old_instant instants
|
||||||
FROM information_schema.global_status
|
FROM information_schema.global_status
|
||||||
WHERE variable_name = 'innodb_instant_alter_column';
|
WHERE variable_name = 'innodb_instant_alter_column';
|
||||||
instants
|
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 t2;
|
||||||
SHOW CREATE TABLE t3;
|
SHOW CREATE TABLE t3;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
SET DEBUG_SYNC=RESET;
|
||||||
--remove_files_wildcard $MYSQLD_DATADIR/test #sql*.frm
|
--remove_files_wildcard $MYSQLD_DATADIR/test #sql*.frm
|
||||||
--list_files $MYSQLD_DATADIR/test
|
--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
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
INSERT INTO t1 VALUES(1, 2);
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
SET DEBUG_SYNC="now SIGNAL alter_progress";
|
SET DEBUG_SYNC="now SIGNAL alter_progress";
|
||||||
disconnect con1;
|
|
||||||
connection default;
|
connection default;
|
||||||
reap;
|
reap;
|
||||||
DROP TABLE t1;
|
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;
|
SET DEBUG_SYNC=reset;
|
||||||
|
CHECK TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
|
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
|
|
||||||
SELECT variable_value-@old_instant instants
|
SELECT variable_value-@old_instant instants
|
||||||
FROM information_schema.global_status
|
FROM information_schema.global_status
|
||||||
WHERE variable_name = 'innodb_instant_alter_column';
|
WHERE variable_name = 'innodb_instant_alter_column';
|
||||||
|
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ start:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!field->fixed_len
|
if (!field->fixed_len
|
||||||
|| (format == REC_LEAF_TEMP
|
|| (format <= REC_LEAF_TEMP_INSTANT
|
||||||
&& !dict_col_get_fixed_size(col, true))) {
|
&& !dict_col_get_fixed_size(col, true))) {
|
||||||
/* Variable-length field: read the length */
|
/* Variable-length field: read the length */
|
||||||
len = *lens--;
|
len = *lens--;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue