summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-08-18 08:52:41 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-08-18 09:12:04 +0300
commite9e051d2972a77224f95563e5555cebd83615d61 (patch)
treebe591bc2b615b876e89acb17552cb3e79300ac4e
parentf2699153810f3c6a65885ef8b87d6be7f834b8bf (diff)
downloadmariadb-git-e9e051d2972a77224f95563e5555cebd83615d61.tar.gz
Follow-up fix to MDEV-12988 backup fails if innodb_undo_tablespaces>0
The fix broke mariabackup --prepare --incremental. The restore of an incremental backup starts up (parts of) InnoDB twice. First, all data files are discovered for applying .delta files. Then, after the .delta files have been applied, InnoDB will be restarted more completely, so that the redo log records will be applied via the buffer pool. During the first startup, the buffer pool is not initialized, and thus trx_rseg_get_n_undo_tablespaces() must not be invoked. The apply of the .delta files will currently assume that the --innodb-undo-tablespaces option correctly specifies the number of undo tablespace files, just like --backup does. The second InnoDB startup of --prepare for applying the redo log will properly invoke trx_rseg_get_n_undo_tablespaces(). enum srv_operation_mode: Add SRV_OPERATION_RESTORE_DELTA for distinguishing the apply of .delta files from SRV_OPERATION_RESTORE. srv_undo_tablespaces_init(): In mariabackup --prepare --incremental, in the initial SRV_OPERATION_RESTORE_DELTA phase, do not invoke trx_rseg_get_n_undo_tablespaces() because the buffer pool or the redo logs are not available. Instead, blindly rely on the parameter --innodb-undo-tablespaces.
-rw-r--r--extra/mariabackup/fil_cur.cc2
-rw-r--r--extra/mariabackup/xtrabackup.cc14
-rw-r--r--storage/innobase/include/srv0srv.h4
-rw-r--r--storage/innobase/srv/srv0start.cc4
4 files changed, 18 insertions, 6 deletions
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index b733f98457e..03f4ce0d7a7 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -159,7 +159,7 @@ xb_fil_cur_open(
/* In the backup mode we should already have a tablespace handle created
by fil_ibd_load() unless it is a system
tablespace. Otherwise we open the file here. */
- if (cursor->is_system() || srv_operation == SRV_OPERATION_RESTORE
+ if (cursor->is_system() || srv_operation == SRV_OPERATION_RESTORE_DELTA
|| xb_close_files) {
node->handle = os_file_create_simple_no_error_handling(
0, node->name,
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 2512bc788e1..3876bd37517 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -2517,9 +2517,11 @@ xb_load_single_table_tablespace(
const char *filname,
bool is_remote)
{
+ ut_ad(srv_operation == SRV_OPERATION_BACKUP
+ || srv_operation == SRV_OPERATION_RESTORE_DELTA);
/* Ignore .isl files on XtraBackup recovery. All tablespaces must be
local. */
- if (is_remote && srv_operation == SRV_OPERATION_RESTORE) {
+ if (is_remote && srv_operation == SRV_OPERATION_RESTORE_DELTA) {
return;
}
if (check_if_skip_table(filname)) {
@@ -2578,7 +2580,8 @@ xb_load_single_table_tablespace(
in the cache to be populated with fields from space header */
fil_space_open(space->name);
- if (srv_operation == SRV_OPERATION_RESTORE || xb_close_files) {
+ if (srv_operation == SRV_OPERATION_RESTORE_DELTA
+ || xb_close_files) {
fil_space_close(space->name);
}
}
@@ -2753,7 +2756,7 @@ xb_load_tablespaces()
lsn_t flush_lsn;
ut_ad(srv_operation == SRV_OPERATION_BACKUP
- || srv_operation == SRV_OPERATION_RESTORE);
+ || srv_operation == SRV_OPERATION_RESTORE_DELTA);
err = srv_sys_space.check_file_spec(&create_new_db, 0);
@@ -4925,6 +4928,8 @@ xtrabackup_prepare_func(char** argv)
srv_thread_concurrency = 1;
if (xtrabackup_incremental) {
+ srv_operation = SRV_OPERATION_RESTORE_DELTA;
+
if (innodb_init_param()) {
error_cleanup:
xb_filters_free();
@@ -4943,7 +4948,6 @@ error_cleanup:
srv_allow_writes_event = os_event_create(0);
os_event_set(srv_allow_writes_event);
#endif
-
dberr_t err = xb_data_files_init();
if (err != DB_SUCCESS) {
msg("xtrabackup: error: xb_data_files_init() failed "
@@ -4976,6 +4980,8 @@ error_cleanup:
if (!ok) goto error_cleanup;
}
+ srv_operation = SRV_OPERATION_RESTORE;
+
if (innodb_init_param()) {
goto error_cleanup;
}
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 891f25f68f1..2fc285270e8 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -507,7 +507,9 @@ enum srv_operation_mode {
/** Mariabackup taking a backup */
SRV_OPERATION_BACKUP,
/** Mariabackup restoring a backup */
- SRV_OPERATION_RESTORE
+ SRV_OPERATION_RESTORE,
+ /** Mariabackup restoring the incremental part of a backup */
+ SRV_OPERATION_RESTORE_DELTA
};
/** Current mode of operation */
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 15e8d89416d..f0b29759423 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -892,11 +892,13 @@ srv_undo_tablespaces_init(bool create_new_db)
already exist. */
n_undo_tablespaces = create_new_db
|| srv_operation == SRV_OPERATION_BACKUP
+ || srv_operation == SRV_OPERATION_RESTORE_DELTA
? srv_undo_tablespaces
: trx_rseg_get_n_undo_tablespaces(undo_tablespace_ids);
srv_undo_tablespaces_active = srv_undo_tablespaces;
switch (srv_operation) {
+ case SRV_OPERATION_RESTORE_DELTA:
case SRV_OPERATION_BACKUP:
/* MDEV-13561 FIXME: Determine srv_undo_space_id_start
from the undo001 file. */
@@ -1317,6 +1319,7 @@ srv_shutdown_all_bg_threads()
switch (srv_operation) {
case SRV_OPERATION_BACKUP:
+ case SRV_OPERATION_RESTORE_DELTA:
break;
case SRV_OPERATION_NORMAL:
case SRV_OPERATION_RESTORE:
@@ -2818,6 +2821,7 @@ innodb_shutdown()
switch (srv_operation) {
case SRV_OPERATION_BACKUP:
case SRV_OPERATION_RESTORE:
+ case SRV_OPERATION_RESTORE_DELTA:
fil_close_all_files();
break;
case SRV_OPERATION_NORMAL: