summaryrefslogtreecommitdiff
path: root/src/cursor/cur_backup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cursor/cur_backup.c')
-rw-r--r--src/cursor/cur_backup.c91
1 files changed, 53 insertions, 38 deletions
diff --git a/src/cursor/cur_backup.c b/src/cursor/cur_backup.c
index 5be9b311a79..4ee23008687 100644
--- a/src/cursor/cur_backup.c
+++ b/src/cursor/cur_backup.c
@@ -10,7 +10,6 @@
static int __backup_all(WT_SESSION_IMPL *);
static int __backup_cleanup_handles(WT_SESSION_IMPL *, WT_CURSOR_BACKUP *);
-static int __backup_file_create(WT_SESSION_IMPL *, WT_CURSOR_BACKUP *, bool);
static int __backup_list_append(
WT_SESSION_IMPL *, WT_CURSOR_BACKUP *, const char *);
static int __backup_list_uri_append(WT_SESSION_IMPL *, const char *, bool *);
@@ -178,8 +177,7 @@ __backup_log_append(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb, bool active)
for (i = 0; i < logcount; i++)
WT_ERR(__backup_list_append(session, cb, logfiles[i]));
}
-err: if (logfiles != NULL)
- __wt_log_files_free(session, logfiles, logcount);
+err: WT_TRET(__wt_fs_directory_list_free(session, &logfiles, logcount));
return (ret);
}
@@ -193,9 +191,13 @@ __backup_start(
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ WT_FSTREAM *srcfs;
+ const char *dest;
bool exist, log_only, target_list;
conn = S2C(session);
+ srcfs = NULL;
+ dest = NULL;
cb->next = 0;
cb->list = NULL;
@@ -224,11 +226,16 @@ __backup_start(
conn->hot_backup = true;
WT_ERR(__wt_writeunlock(session, conn->hot_backup_lock));
- /* Create the hot backup file. */
- WT_ERR(__backup_file_create(session, cb, false));
-
- /* Add log files if logging is enabled. */
-
+ /*
+ * Create a temporary backup file. This must be opened before
+ * generating the list of targets in backup_uri. This file will
+ * later be renamed to the correct name depending on whether or not
+ * we're doing an incremental backup. We need a temp file so that if
+ * we fail or crash while filling it, the existence of a partial file
+ * doesn't confuse restarting in the source database.
+ */
+ WT_ERR(__wt_fopen(session, WT_BACKUP_TMP,
+ WT_OPEN_CREATE, WT_STREAM_WRITE, &cb->bfs));
/*
* If a list of targets was specified, work our way through them.
* Else, generate a list of all database objects.
@@ -248,20 +255,23 @@ __backup_start(
/* Add the hot backup and standard WiredTiger files to the list. */
if (log_only) {
/*
- * Close any hot backup file.
- * We're about to open the incremental backup file.
+ * We also open an incremental backup source file so that we
+ * can detect a crash with an incremental backup existing in
+ * the source directory versus an improper destination.
*/
- WT_TRET(__wt_close(session, &cb->bfh));
- WT_ERR(__backup_file_create(session, cb, log_only));
+ dest = WT_INCREMENTAL_BACKUP;
+ WT_ERR(__wt_fopen(session, WT_INCREMENTAL_SRC,
+ WT_OPEN_CREATE, WT_STREAM_WRITE, &srcfs));
WT_ERR(__backup_list_append(
session, cb, WT_INCREMENTAL_BACKUP));
} else {
+ dest = WT_METADATA_BACKUP;
WT_ERR(__backup_list_append(session, cb, WT_METADATA_BACKUP));
- WT_ERR(__wt_exist(session, WT_BASECONFIG, &exist));
+ WT_ERR(__wt_fs_exist(session, WT_BASECONFIG, &exist));
if (exist)
WT_ERR(__backup_list_append(
session, cb, WT_BASECONFIG));
- WT_ERR(__wt_exist(session, WT_USERCONFIG, &exist));
+ WT_ERR(__wt_fs_exist(session, WT_USERCONFIG, &exist));
if (exist)
WT_ERR(__backup_list_append(
session, cb, WT_USERCONFIG));
@@ -269,10 +279,15 @@ __backup_start(
}
err: /* Close the hot backup file. */
- WT_TRET(__wt_close(session, &cb->bfh));
+ WT_TRET(__wt_fclose(session, &cb->bfs));
+ if (srcfs != NULL)
+ WT_TRET(__wt_fclose(session, &srcfs));
if (ret != 0) {
WT_TRET(__backup_cleanup_handles(session, cb));
WT_TRET(__backup_stop(session));
+ } else {
+ WT_ASSERT(session, dest != NULL);
+ WT_TRET(__wt_fs_rename(session, WT_BACKUP_TMP, dest));
}
return (ret);
@@ -384,13 +399,23 @@ __backup_uri(WT_SESSION_IMPL *session,
uri);
/*
- * Handle log targets. We do not need to go through the
- * schema worker, just call the function to append them.
- * Set log_only only if it is our only URI target.
+ * Handle log targets. We do not need to go through the schema
+ * worker, just call the function to append them. Set log_only
+ * only if it is our only URI target.
*/
if (WT_PREFIX_MATCH(uri, "log:")) {
+ /*
+ * Log archive cannot mix with incremental backup, don't
+ * let that happen.
+ */
+ if (FLD_ISSET(
+ S2C(session)->log_flags, WT_CONN_LOG_ARCHIVE))
+ WT_ERR_MSG(session, EINVAL,
+ "incremental backup not possible when "
+ "automatic log archival configured");
*log_only = !target_list;
- WT_ERR(__backup_list_uri_append(session, uri, NULL));
+ WT_ERR(__backup_log_append(
+ session, session->bkp_cursor, false));
} else {
*log_only = false;
WT_ERR(__wt_schema_worker(session,
@@ -404,19 +429,6 @@ err: __wt_scr_free(session, &tmp);
}
/*
- * __backup_file_create --
- * Create the meta-data backup file.
- */
-static int
-__backup_file_create(
- WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb, bool incremental)
-{
- return (__wt_open(session,
- incremental ? WT_INCREMENTAL_BACKUP : WT_METADATA_BACKUP,
- WT_FILE_TYPE_REGULAR, WT_OPEN_CREATE | WT_STREAM_WRITE, &cb->bfh));
-}
-
-/*
* __wt_backup_file_remove --
* Remove the incremental and meta-data backup files.
*/
@@ -425,7 +437,15 @@ __wt_backup_file_remove(WT_SESSION_IMPL *session)
{
WT_DECL_RET;
+ /*
+ * Note that order matters for removing the incremental files. We must
+ * remove the backup file before removing the source file so that we
+ * always know we were a source directory while there's any chance of
+ * an incremental backup file existing.
+ */
+ WT_TRET(__wt_remove_if_exists(session, WT_BACKUP_TMP));
WT_TRET(__wt_remove_if_exists(session, WT_INCREMENTAL_BACKUP));
+ WT_TRET(__wt_remove_if_exists(session, WT_INCREMENTAL_SRC));
WT_TRET(__wt_remove_if_exists(session, WT_METADATA_BACKUP));
return (ret);
}
@@ -453,11 +473,6 @@ __backup_list_uri_append(
* if there's an entry backed by anything other than a file or lsm
* entry, we're confused.
*/
- if (WT_PREFIX_MATCH(name, "log:")) {
- WT_RET(__backup_log_append(session, cb, false));
- return (0);
- }
-
if (!WT_PREFIX_MATCH(name, "file:") &&
!WT_PREFIX_MATCH(name, "colgroup:") &&
!WT_PREFIX_MATCH(name, "index:") &&
@@ -473,7 +488,7 @@ __backup_list_uri_append(
/* Add the metadata entry to the backup file. */
WT_RET(__wt_metadata_search(session, name, &value));
- ret = __wt_fprintf(session, cb->bfh, "%s\n%s\n", name, value);
+ ret = __wt_fprintf(session, cb->bfs, "%s\n%s\n", name, value);
__wt_free(session, value);
WT_RET(ret);