Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
/*
 * __wt_turtle_read --
 *	Read the turtle file.
 */
int
__wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep)
{
	FILE *fp;
	WT_DECL_ITEM(buf);
	WT_DECL_RET;
	int match;
	char *path;

	*valuep = NULL;

	fp = NULL;
	path = NULL;

	/*
	 * Open the turtle file; there's one case where we won't find the turtle
	 * file, yet still succeed.  We create the metadata file before creating
	 * the turtle file, and that means returning the default configuration
	 * string for the metadata file.
	 */
	WT_RET(__wt_filename(session, WT_METADATA_TURTLE, &path));
	if ((fp = fopen(path, "r")) == NULL)
		ret = __wt_errno();
	__wt_free(session, path);
	if (fp == NULL)
		return (strcmp(key, WT_METAFILE_URI) == 0 ?
		    __metadata_config(session, valuep) : ret);

	/* Search for the key. */
	WT_ERR(__wt_scr_alloc(session, 512, &buf));
	for (match = 0;;) {
		WT_ERR(__wt_getline(session, buf, fp));
		if (buf->size == 0)
			WT_ERR(WT_NOTFOUND);
		if (strcmp(key, buf->data) == 0)
			match = 1;

		/* Key matched: read the subsequent line for the value. */
		WT_ERR(__wt_getline(session, buf, fp));
		if (buf->size == 0)
			WT_ERR(__wt_illegal_value(session, WT_METADATA_TURTLE));
		if (match)
			break;
	}

	/* Copy the value for the caller. */
	WT_ERR(__wt_strdup(session, buf->data, valuep));

err:	if (fp != NULL)
		WT_TRET(fclose(fp) == 0 ? 0 : __wt_errno());
	__wt_scr_free(&buf);
	return (ret);
}
Ejemplo n.º 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;
	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_exist(session, WT_METADATA_TURTLE_SET, &exist));
	if (exist)
		WT_RET(__wt_remove(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.
	 *
	 * If there's already a turtle file, we're done.
	 */
	WT_RET(__wt_exist(session, WT_METADATA_TURTLE, &exist));
	if (exist)
		return (0);

	/* 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 file if it exists, we'll never read it again. */
	WT_ERR(__wt_exist(session, WT_METADATA_BACKUP, &exist));
	if (exist)
		WT_ERR(__wt_remove(session, WT_METADATA_BACKUP));

err:	__wt_free(session, metaconf);
	return (ret);
}
Ejemplo n.º 4
0
/*
 * __wt_turtle_read --
 *	Read the turtle file.
 */
int
__wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep)
{
	WT_DECL_ITEM(buf);
	WT_DECL_RET;
	WT_FSTREAM *fs;
	bool exist, match;

	*valuep = NULL;

	/*
	 * Open the turtle file; there's one case where we won't find the turtle
	 * file, yet still succeed.  We create the metadata file before creating
	 * the turtle file, and that means returning the default configuration
	 * string for the metadata file.
	 */
	WT_RET(__wt_fs_exist(session, WT_METADATA_TURTLE, &exist));
	if (!exist)
		return (strcmp(key, WT_METAFILE_URI) == 0 ?
		    __metadata_config(session, valuep) : WT_NOTFOUND);
	WT_RET(__wt_fopen(session, WT_METADATA_TURTLE, 0, WT_STREAM_READ, &fs));

	/* Search for the key. */
	WT_ERR(__wt_scr_alloc(session, 512, &buf));
	for (match = false;;) {
		WT_ERR(__wt_getline(session, fs, buf));
		if (buf->size == 0)
			WT_ERR(WT_NOTFOUND);
		if (strcmp(key, buf->data) == 0)
			match = true;

		/* Key matched: read the subsequent line for the value. */
		WT_ERR(__wt_getline(session, fs, buf));
		if (buf->size == 0)
			WT_ERR(__wt_illegal_value(session, WT_METADATA_TURTLE));
		if (match)
			break;
	}

	/* Copy the value for the caller. */
	WT_ERR(__wt_strdup(session, buf->data, valuep));

err:	WT_TRET(__wt_fclose(session, &fs));
	__wt_scr_free(session, &buf);

	if (ret != 0)
		__wt_free(session, *valuep);
	return (ret);
}
Ejemplo n.º 5
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);
}