Exemple #1
0
/*
 * __wt_backup_file_remove --
 *	Remove the incremental and meta-data backup files.
 */
int
__wt_backup_file_remove(WT_SESSION_IMPL *session)
{
	WT_DECL_RET;

	WT_TRET(__wt_remove_if_exists(session, WT_INCREMENTAL_BACKUP));
	WT_TRET(__wt_remove_if_exists(session, WT_METADATA_BACKUP));
	return (ret);
}
Exemple #2
0
/*
 * __wt_turtle_update --
 *	Update the turtle file.
 */
int
__wt_turtle_update(WT_SESSION_IMPL *session, const char *key, const char *value)
{
	WT_FSTREAM *fs;
	WT_DECL_RET;
	int vmajor, vminor, vpatch;
	const char *version;

	fs = NULL;

	/*
	 * Create the turtle setup file: we currently re-write it from scratch
	 * every time.
	 */
	WT_RET(__wt_fopen(session, WT_METADATA_TURTLE_SET,
	    WT_FS_OPEN_CREATE | WT_FS_OPEN_EXCLUSIVE, WT_STREAM_WRITE, &fs));

	version = wiredtiger_version(&vmajor, &vminor, &vpatch);
	WT_ERR(__wt_fprintf(session, fs,
	    "%s\n%s\n%s\n" "major=%d,minor=%d,patch=%d\n%s\n%s\n",
	    WT_METADATA_VERSION_STR, version,
	    WT_METADATA_VERSION, vmajor, vminor, vpatch,
	    key, value));

	/* Flush the stream and rename the file into place. */
	ret = __wt_sync_and_rename(
	    session, &fs, WT_METADATA_TURTLE_SET, WT_METADATA_TURTLE);

	/* Close any file handle left open, remove any temporary file. */
err:	WT_TRET(__wt_fclose(session, &fs));
	WT_TRET(__wt_remove_if_exists(session, WT_METADATA_TURTLE_SET, false));

	return (ret);
}
Exemple #3
0
/*
 * __wt_turtle_init --
 *	Check the turtle file and create if necessary.
 */
int
__wt_turtle_init(WT_SESSION_IMPL *session)
{
	WT_DECL_RET;
	int exist, exist_incr;
	char *metaconf;

	metaconf = NULL;

	/*
	 * Discard any turtle setup file left-over from previous runs.  This
	 * doesn't matter for correctness, it's just cleaning up random files.
	 */
	WT_RET(__wt_remove_if_exists(session, WT_METADATA_TURTLE_SET));

	/*
	 * We could die after creating the turtle file and before creating the
	 * metadata file, or worse, the metadata file might be in some random
	 * state.  Make sure that doesn't happen: if we don't find the turtle
	 * file, first create the metadata file, load any hot backup, and then
	 * create the turtle file.  No matter what happens, if metadata file
	 * creation doesn't fully complete, we won't have a turtle file and we
	 * will repeat the process until we succeed.
	 *
	 * Incremental backups can occur only run recovery is run and it becomes
	 * live.  So if there is a turtle file and an incremental backup file
	 * that is an error.  Otherwise, if there's already a turtle file,
	 * we're done.
	 */
	WT_RET(__wt_exist(session, WT_INCREMENTAL_BACKUP, &exist_incr));
	WT_RET(__wt_exist(session, WT_METADATA_TURTLE, &exist));
	if (exist) {
		if (exist_incr)
			WT_RET_MSG(session, EINVAL,
			    "Incremental backup after running recovery "
			    "is not allowed.");
		return (0);
	}
	if (exist_incr)
		F_SET(S2C(session), WT_CONN_WAS_BACKUP);

	/* Create the metadata file. */
	WT_RET(__metadata_init(session));

	/* Load any hot-backup information. */
	WT_RET(__metadata_load_hot_backup(session));

	/* Create any bulk-loaded file stubs. */
	WT_RET(__metadata_load_bulk(session));

	/* Create the turtle file. */
	WT_RET(__metadata_config(session, &metaconf));
	WT_ERR(__wt_turtle_update(session, WT_METAFILE_URI, metaconf));

	/* Remove the backup files, we'll never read them again. */
	WT_ERR(__wt_backup_file_remove(session));

err:	__wt_free(session, metaconf);
	return (ret);
}
Exemple #4
0
/*
 * __wt_backup_file_remove --
 *	Remove the incremental and meta-data backup files.
 */
int
__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, true));
	WT_TRET(__wt_remove_if_exists(session, WT_INCREMENTAL_BACKUP, true));
	WT_TRET(__wt_remove_if_exists(session, WT_INCREMENTAL_SRC, true));
	WT_TRET(__wt_remove_if_exists(session, WT_METADATA_BACKUP, true));
	return (ret);
}
Exemple #5
0
/*
 * __meta_track_apply --
 *	Apply the changes in a metadata tracking record.
 */
static int
__meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk)
{
	WT_BM *bm;
	WT_BTREE *btree;
	WT_DECL_RET;
	int tret;

	switch (trk->op) {
	case WT_ST_EMPTY:	/* Unused slot */
		break;
	case WT_ST_CHECKPOINT:	/* Checkpoint, see above */
		btree = trk->dhandle->handle;
		bm = btree->bm;
		WT_WITH_DHANDLE(session, trk->dhandle,
		    WT_TRET(bm->checkpoint_resolve(bm, session)));
		break;
	case WT_ST_DROP_COMMIT:
		if ((tret = __wt_remove_if_exists(session, trk->a)) != 0) {
			__wt_err(session, tret,
			    "metadata remove dropped file %s",
			    trk->a);
			WT_TRET(tret);
		}
		break;
	case WT_ST_LOCK:
		WT_WITH_DHANDLE(session, trk->dhandle,
		    WT_TRET(__wt_session_release_btree(session)));
		break;
	case WT_ST_FILEOP:
	case WT_ST_REMOVE:
	case WT_ST_SET:
		break;
	WT_ILLEGAL_VALUE(session);
	}

	__meta_track_clear(session, trk);
	return (ret);
}
Exemple #6
0
/*
 * __wt_turtle_update --
 *	Update the turtle file.
 */
int
__wt_turtle_update(
    WT_SESSION_IMPL *session, const char *key,  const char *value)
{
	WT_FH *fh;
	WT_DECL_ITEM(buf);
	WT_DECL_RET;
	int vmajor, vminor, vpatch;
	const char *version;

	fh = NULL;

	/*
	 * Create the turtle setup file: we currently re-write it from scratch
	 * every time.
	 */
	WT_RET(__wt_open(
	    session, WT_METADATA_TURTLE_SET, 1, 1, WT_FILE_TYPE_TURTLE, &fh));

	version = wiredtiger_version(&vmajor, &vminor, &vpatch);
	WT_ERR(__wt_scr_alloc(session, 2 * 1024, &buf));
	WT_ERR(__wt_buf_fmt(session, buf,
	    "%s\n%s\n%s\n" "major=%d,minor=%d,patch=%d\n%s\n%s\n",
	    WT_METADATA_VERSION_STR, version,
	    WT_METADATA_VERSION, vmajor, vminor, vpatch,
	    key, value));
	WT_ERR(__wt_write(session, fh, 0, buf->size, buf->data));

	/* Flush the handle and rename the file into place. */
	ret = __wt_sync_and_rename_fh(
	    session, &fh, WT_METADATA_TURTLE_SET, WT_METADATA_TURTLE);

	/* Close any file handle left open, remove any temporary file. */
err:	WT_TRET(__wt_close(session, &fh));
	WT_TRET(__wt_remove_if_exists(session, WT_METADATA_TURTLE_SET));

	__wt_scr_free(session, &buf);
	return (ret);
}
Exemple #7
0
/*
 * __wt_turtle_init --
 *	Check the turtle file and create if necessary.
 */
int
__wt_turtle_init(WT_SESSION_IMPL *session)
{
	WT_DECL_RET;
	bool exist_backup, exist_incr, exist_isrc, exist_turtle, load;
	char *metaconf;

	metaconf = NULL;
	load = false;

	/*
	 * Discard any turtle setup file left-over from previous runs.  This
	 * doesn't matter for correctness, it's just cleaning up random files.
	 */
	WT_RET(__wt_remove_if_exists(session, WT_METADATA_TURTLE_SET, false));

	/*
	 * We could die after creating the turtle file and before creating the
	 * metadata file, or worse, the metadata file might be in some random
	 * state.  Make sure that doesn't happen: if we don't find the turtle
	 * file, first create the metadata file, load any hot backup, and then
	 * create the turtle file.  No matter what happens, if metadata file
	 * creation doesn't fully complete, we won't have a turtle file and we
	 * will repeat the process until we succeed.
	 *
	 * Incremental backups can occur only if recovery is run and it becomes
	 * live. So, if there is a turtle file and an incremental backup file,
	 * that is an error.  Otherwise, if there's already a turtle file, we're
	 * done.
	 */
	WT_RET(__wt_fs_exist(session, WT_INCREMENTAL_BACKUP, &exist_incr));
	WT_RET(__wt_fs_exist(session, WT_INCREMENTAL_SRC, &exist_isrc));
	WT_RET(__wt_fs_exist(session, WT_METADATA_BACKUP, &exist_backup));
	WT_RET(__wt_fs_exist(session, WT_METADATA_TURTLE, &exist_turtle));
	if (exist_turtle) {
		/*
		 * We need to detect the difference between a source database
		 * that may have crashed with an incremental backup file
		 * and a destination database that incorrectly ran recovery.
		 */
		if (exist_incr && !exist_isrc)
			WT_RET_MSG(session, EINVAL,
			    "Incremental backup after running recovery "
			    "is not allowed");
		/*
		 * If we have a backup file and metadata and turtle files,
		 * we want to recreate the metadata from the backup.
		 */
		if (exist_backup) {
			WT_RET(__wt_msg(session,
			    "Both %s and %s exist; recreating metadata from "
			    "backup",
			    WT_METADATA_TURTLE, WT_METADATA_BACKUP));
			WT_RET(
			    __wt_remove_if_exists(session, WT_METAFILE, false));
			WT_RET(__wt_remove_if_exists(
			    session, WT_METADATA_TURTLE, false));
			load = true;
		}
	} else
		load = true;
	if (load) {
		if (exist_incr)
			F_SET(S2C(session), WT_CONN_WAS_BACKUP);

		/* Create the metadata file. */
		WT_RET(__metadata_init(session));

		/* Load any hot-backup information. */
		WT_RET(__metadata_load_hot_backup(session));

		/* Create any bulk-loaded file stubs. */
		WT_RET(__metadata_load_bulk(session));

		/* Create the turtle file. */
		WT_RET(__metadata_config(session, &metaconf));
		WT_WITH_TURTLE_LOCK(session, ret,
		    ret = __wt_turtle_update(
		    session, WT_METAFILE_URI, metaconf));
		WT_ERR(ret);
	}

	/* Remove the backup files, we'll never read them again. */
	WT_ERR(__wt_backup_file_remove(session));

err:	__wt_free(session, metaconf);
	return (ret);
}
Exemple #8
0
	ffh = tfh = NULL;
	buf = NULL;

	/*
	 * Remove the target file if it exists, then create a temporary file,
	 * copy the original into it and rename it into place. I don't think
	 * its necessary to remove the file, or create a copy and do a rename,
	 * it's likely safe to overwrite the backup file directly. I'm doing
	 * the remove and rename to insulate us from errors in other programs
	 * that might not detect a corrupted backup file; it's cheap insurance
	 * in a path where undetected failure is very bad.
	 */
	WT_ERR(__wt_scr_alloc(session, 0, &tmp));
	WT_ERR(__wt_buf_fmt(session, tmp, "%s.copy", to));

	WT_ERR(__wt_remove_if_exists(session, to, false));
	WT_ERR(__wt_remove_if_exists(session, tmp->data, false));

	/* Open the from and temporary file handles. */
	WT_ERR(__wt_open(session, from, WT_FS_OPEN_FILE_TYPE_REGULAR, 0, &ffh));
	WT_ERR(__wt_open(session, tmp->data, WT_FS_OPEN_FILE_TYPE_REGULAR,
	    WT_FS_OPEN_CREATE | WT_FS_OPEN_EXCLUSIVE, &tfh));

	/*
	 * Allocate a copy buffer. Don't use a scratch buffer, this thing is
	 * big, and we don't want it hanging around.
	 */
#define	WT_BACKUP_COPY_SIZE	(128 * 1024)
	WT_ERR(__wt_malloc(session, WT_BACKUP_COPY_SIZE, &buf));

	/* Get the file's size, then copy the bytes. */