Skip to content

Commit

Permalink
MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
Browse files Browse the repository at this point in the history
row_undo_ins_parse_undo_rec(): Do not try to read non-existing
virtual column information for the metadata record.
  • Loading branch information
dr-m committed Dec 1, 2020
1 parent 81ab9ea commit 73f3433
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
29 changes: 26 additions & 3 deletions mysql-test/suite/innodb/r/instant_alter_crash.result
Expand Up @@ -42,7 +42,6 @@ SET debug_dbug='+d,dict_sys_mutex_avoid';
DELETE FROM t1;
# Kill the server
disconnect ddl;
SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
FOUND 2 /\[Note\] InnoDB: Rolled back recovered transaction / in mysqld.1.err
SELECT * FROM t1;
Expand Down Expand Up @@ -93,6 +92,22 @@ header=0x060008030000 (id=0x73757072656d756d00)
UNLOCK TABLES;
DELETE FROM t2;
InnoDB 0 transactions not purged
#
# MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
#
connect ddl, localhost, root;
CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2))
ENGINE=InnoDB;
INSERT INTO t3 SET id=1,c2=1;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET debug_dbug='+d,dict_sys_mutex_avoid';
INSERT INTO t1 VALUES(0,0);
# Kill the server
disconnect ddl;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
Expand All @@ -110,6 +125,14 @@ t2 CREATE TABLE `t2` (
PRIMARY KEY (`id`),
UNIQUE KEY `c2` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
DROP TABLE t1,t2;
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`c2` int(11) DEFAULT NULL,
`v2` int(11) GENERATED ALWAYS AS (`c2`) VIRTUAL,
PRIMARY KEY (`id`),
UNIQUE KEY `v2` (`v2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t3;
db.opt
SET GLOBAL innodb_purge_rseg_truncate_frequency=@saved_frequency;
28 changes: 24 additions & 4 deletions mysql-test/suite/innodb/t/instant_alter_crash.test
Expand Up @@ -61,7 +61,6 @@ DELETE FROM t1;
disconnect ddl;
--source include/start_mysqld.inc

SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;

let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
Expand Down Expand Up @@ -124,11 +123,32 @@ UNLOCK TABLES;
DELETE FROM t2;
--source include/wait_all_purged.inc

--echo #
--echo # MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
--echo #
connect ddl, localhost, root;
CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2))
ENGINE=InnoDB;
INSERT INTO t3 SET id=1,c2=1;

SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
--send
ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi';

connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET debug_dbug='+d,dict_sys_mutex_avoid';
INSERT INTO t1 VALUES(0,0);

--source include/kill_mysqld.inc
disconnect ddl;
--source include/start_mysqld.inc

SHOW CREATE TABLE t1;
SHOW CREATE TABLE t2;
DROP TABLE t1,t2;
SHOW CREATE TABLE t3;
DROP TABLE t1,t2,t3;

--remove_files_wildcard $MYSQLD_DATADIR/test #sql*.frm
--list_files $MYSQLD_DATADIR/test

SET GLOBAL innodb_purge_rseg_truncate_frequency=@saved_frequency;
7 changes: 7 additions & 0 deletions storage/innobase/row/row0uins.cc
Expand Up @@ -459,6 +459,13 @@ row_undo_ins_parse_undo_rec(
node->heap);
} else {
node->ref = &trx_undo_metadata;
if (!row_undo_search_clust_to_pcur(node)) {
/* An error probably occurred during
an insert into the clustered index,
after we wrote the undo log record. */
goto close_table;
}
return;
}

if (!row_undo_search_clust_to_pcur(node)) {
Expand Down

0 comments on commit 73f3433

Please sign in to comment.