Skip to content

Commit fb9da7f

Browse files
MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare
mariadb-backup with --prepare option could result in empty redo log file. When --prepare is followed by --prepare --export, we exit early in srv_start function without opening the ibdata1 tablespace. Later while trying to read rollback segment header page, we hit the debug assert which claims that the system space should already have been opened. There are two assert cases here. Issue-1: System tablespace object is not there in fil space hash i.e. srv_sys_space.open_or_create() is not called. Issue-2: The system tablespace data file ibdata1 is not opened i.e. fil_system.sys_space->open() is not called. Fix: For empty redo log and restore operation, open system tablespace before returning.
1 parent f5373db commit fb9da7f

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

mysql-test/suite/mariabackup/partial.result

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ ALTER TABLE t1 IMPORT TABLESPACE;
1414
SELECT * FROM t1;
1515
i
1616
1
17+
# MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare
18+
t1.cfg
19+
t21.cfg
20+
ALTER TABLE t1 DISCARD TABLESPACE;
21+
ALTER TABLE t1 IMPORT TABLESPACE;
22+
SELECT * FROM t1;
23+
i
24+
1
1725
DROP TABLE t1;
1826
DROP TABLE t2;
1927
DROP TABLE t21;

mysql-test/suite/mariabackup/partial.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,25 @@ copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
5454
ALTER TABLE t1 IMPORT TABLESPACE;
5555

5656
SELECT * FROM t1;
57+
58+
--echo # MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare
59+
--disable_result_log
60+
exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --target-dir=$targetdir;
61+
exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir;
62+
--enable_result_log
63+
64+
list_files $targetdir/test *.cfg;
65+
# There must not be binary logs created on --prepare step
66+
list_files $targetdir/ mysqld-bin.*;
67+
68+
let $MYSQLD_DATADIR= `select @@datadir`;
69+
ALTER TABLE t1 DISCARD TABLESPACE;
70+
copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd;
71+
copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
72+
ALTER TABLE t1 IMPORT TABLESPACE;
73+
74+
SELECT * FROM t1;
75+
5776
DROP TABLE t1;
5877
DROP TABLE t2;
5978
DROP TABLE t21;

storage/innobase/srv/srv0start.cc

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,36 @@ dberr_t srv_start(bool create_new_db)
12771277
return srv_init_abort(DB_ERROR);
12781278
}
12791279

1280+
/* Open system tablespace and undo spaces. It is a special case for
1281+
restore with empty redo log file. We support restore in such case and
1282+
proceed after opening system tablespaces. */
1283+
ulint sum_of_new_sizes;
1284+
1285+
auto open_system_spaces = [&]() {
1286+
ut_ad(!create_new_db);
1287+
ut_ad(srv_operation == SRV_OPERATION_RESTORE ||
1288+
srv_operation == SRV_OPERATION_RESTORE_EXPORT);
1289+
1290+
/* Open system tablespace ibdata1. */
1291+
auto err = srv_sys_space.open_or_create(
1292+
false, false, &sum_of_new_sizes, &flushed_lsn);
1293+
if (err != DB_SUCCESS) {
1294+
return srv_init_abort(err);
1295+
}
1296+
1297+
/* Open data files for system tablespace. */
1298+
if (!fil_system.sys_space->open(false)) {
1299+
return srv_init_abort(DB_ERROR);
1300+
}
1301+
1302+
/* Open undo tablespaces. */
1303+
err = srv_undo_tablespaces_init(false);
1304+
if (err != DB_SUCCESS) {
1305+
return srv_init_abort(err);
1306+
}
1307+
return DB_SUCCESS;
1308+
};
1309+
12801310
std::string logfile0;
12811311
bool create_new_log = create_new_db;
12821312
if (create_new_db) {
@@ -1299,7 +1329,8 @@ dberr_t srv_start(bool create_new_db)
12991329
bool log_file_found;
13001330
if (dberr_t err = find_and_check_log_file(log_file_found)) {
13011331
if (err == DB_NOT_FOUND) {
1302-
return DB_SUCCESS;
1332+
/* For restore, we need to continue. */
1333+
return open_system_spaces();
13031334
}
13041335
return srv_init_abort(err);
13051336
}
@@ -1329,8 +1360,6 @@ dberr_t srv_start(bool create_new_db)
13291360
}
13301361

13311362
/* Open or create the data files. */
1332-
ulint sum_of_new_sizes;
1333-
13341363
err = srv_sys_space.open_or_create(
13351364
false, create_new_db, &sum_of_new_sizes, &flushed_lsn);
13361365

@@ -1378,10 +1407,8 @@ dberr_t srv_start(bool create_new_db)
13781407
/* Suppress the message about
13791408
crash recovery. */
13801409
flushed_lsn = log_sys.get_lsn();
1381-
goto file_checked;
13821410
}
13831411

1384-
file_checked:
13851412
/* Open data files in the systemtablespace: we keep
13861413
them open until database shutdown */
13871414
ut_d(fil_system.sys_space->recv_size = srv_sys_space_size_debug);

0 commit comments

Comments
 (0)