コード例 #1
0
ファイル: util_load.c プロジェクト: deepinit-arek/wiredtiger
int
util_load(WT_SESSION *session, int argc, char *argv[])
{
	int ch;
	const char *filename;
	uint32_t flags;

	flags = 0;

	filename = "<stdin>";
	while ((ch = __wt_getopt(progname, argc, argv, "af:jnr:")) != EOF)
		switch (ch) {
		case 'a':	/* append (ignore record number keys) */
			append = 1;
			break;
		case 'f':	/* input file */
			if (freopen(__wt_optarg, "r", stdin) == NULL)
				return (
				    util_err(errno, "%s: reopen", __wt_optarg));
			else
				filename = __wt_optarg;
			break;
		case 'j':	/* input is JSON */
			json = 1;
			break;
		case 'n':	/* don't overwrite existing data */
			no_overwrite = 1;
			break;
		case 'r':	/* rename */
			cmdname = __wt_optarg;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* -a and -o are mutually exclusive. */
	if (append == 1 && no_overwrite == 1)
		return (util_err(EINVAL,
		    "the -a (append) and -n (no-overwrite) flags are mutually "
		    "exclusive"));

	/* The remaining arguments are configuration uri/string pairs. */
	if (argc != 0) {
		if (argc % 2 != 0)
			return (usage());
		cmdconfig = argv;
	}

	if (json) {
		if (append)
			flags |= LOAD_JSON_APPEND;
		if (no_overwrite)
			flags |= LOAD_JSON_NO_OVERWRITE;
		return (util_load_json(session, filename, flags));
	} else
		return (load_dump(session));
}
コード例 #2
0
int
util_create(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	const char *config, *uri;

	config = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "c:")) != EOF)
		switch (ch) {
		case 'c':			/* command-line configuration */
			config = __wt_optarg;
			break;
		case '?':
		default:
			return (usage());
		}

	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining argument is the uri. */
	if (argc != 1)
		return (usage());

	if ((uri = util_name(*argv, "table")) == NULL)
		return (1);

	if ((ret = session->create(session, uri, config)) != 0)
		return (util_err(ret, "%s: session.create", uri));
	return (0);
}
コード例 #3
0
ファイル: util_drop.c プロジェクト: AlexOreshkevich/mongo
int
util_drop(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char *name;

	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}

	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining argument is the uri. */
	if (argc != 1)
		return (usage());
	if ((name = util_name(session, *argv, "table")) == NULL)
		return (1);

	ret = session->drop(session, name, "force");

	free(name);
	return (ret);
}
コード例 #4
0
int
util_alter(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char **configp;

	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}

	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining arguments are uri/string pairs. */
	if (argc % 2 != 0)
		return (usage());

	for (configp = argv; *configp != NULL; configp += 2)
		if ((ret = session->alter(
		    session, configp[0], configp[1])) != 0) {
			(void)util_err(session, ret,
			    "session.alter: %s, %s", configp[0], configp[1]);
			return (1);
		}
	return (0);
}
コード例 #5
0
int
util_downgrade(WT_SESSION *session, WT_CONNECTION *conn, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char config_str[128], *release;

	release = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "V:")) != EOF)
		switch (ch) {
		case 'V':
			release = __wt_optarg;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;

	/*
	 * The release argument is required.
	 * There should not be any more arguments.
	 */
	if (argc != 0 || release == NULL)
		return (usage());

	if ((ret = __wt_snprintf(config_str, sizeof(config_str),
	    "compatibility=(release=%s)", release)) != 0)
		return (util_err(session, ret, NULL));
	if ((ret = conn->reconfigure(conn, config_str)) != 0)
		return (util_err(session, ret, "conn.downgrade"));

	return (0);
}
コード例 #6
0
ファイル: util_backup.c プロジェクト: 7segments/mongo-1
int
util_backup(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	int ch;
	char *config;
	const char *directory, *name;

	config = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "t:")) != EOF)
		switch (ch) {
		case 't':
			if (append_target(session, __wt_optarg, &config))
				return (1);
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	if (argc != 1) {
		(void)usage();
		goto err;
	}
	directory = *argv;

	if ((ret = session->open_cursor(
	    session, "backup:", NULL, config, &cursor)) != 0) {
		fprintf(stderr, "%s: cursor open(backup:) failed: %s\n",
		    progname, session->strerror(session, ret));
		goto err;
	}

	/* Copy the files. */
	while (
	    (ret = cursor->next(cursor)) == 0 &&
	    (ret = cursor->get_key(cursor, &name)) == 0)
		if ((ret = copy(name, directory)) != 0)
			goto err;
	if (ret == WT_NOTFOUND)
		ret = 0;

	if (ret != 0) {
		fprintf(stderr, "%s: cursor next(backup:) failed: %s\n",
		    progname, session->strerror(session, ret));
		goto err;
	}

err:	if (config != NULL)
		free(config);
	if (cbuf != NULL)
		free(cbuf);

	return (ret);
}
コード例 #7
0
ファイル: huge.c プロジェクト: Arikes/mongo
int
main(int argc, char *argv[])
{
	CONFIG *cp;
	size_t len, *lp;
	int ch, small;
	char *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	small = 0;
	working_dir = NULL;

	while ((ch = __wt_getopt(progname, argc, argv, "h:s")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 's':			/* Gigabytes */
			small = 1;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, 512, working_dir);

	/* Allocate a buffer to use. */
	len = small ? ((size_t)SMALL_MAX) : ((size_t)4 * GIGABYTE);
	if ((big = malloc(len)) == NULL)
		testutil_die(errno, "");
	memset(big, 'a', len);

	/* Make sure the configurations all work. */
	for (lp = lengths; *lp != 0; ++lp) {
		if (small && *lp > SMALL_MAX)
			break;
		for (cp = config; cp->uri != NULL; ++cp) {
			if (!cp->recno)		/* Big key on row-store */
				run(cp, 1, *lp);
			run(cp, 0, *lp);	/* Big value */
		}
	}
	free(big);

	testutil_clean_work_dir(home);

	return (EXIT_SUCCESS);
}
コード例 #8
0
ファイル: salvage.c プロジェクト: Machyne/mongo
int
main(int argc, char *argv[])
{
	u_int ptype;
	int ch, r;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	r = 0;
	ptype = 0;
	while ((ch = __wt_getopt(progname, argc, argv, "r:t:v")) != EOF)
		switch (ch) {
		case 'r':
			r = atoi(__wt_optarg);
			if (r == 0)
				return (usage());
			break;
		case 't':
			if (strcmp(__wt_optarg, "fix") == 0)
				ptype = WT_PAGE_COL_FIX;
			else if (strcmp(__wt_optarg, "var") == 0)
				ptype = WT_PAGE_COL_VAR;
			else if (strcmp(__wt_optarg, "row") == 0)
				ptype = WT_PAGE_ROW_LEAF;
			else
				return (usage());
			break;
		case 'v':
			verbose = 1;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		return (usage());

	printf("salvage test run started\n");

	t(r, ptype, 1);
	t(r, ptype, 0);

	printf("salvage test run completed\n");
	return (EXIT_SUCCESS);
}
コード例 #9
0
ファイル: test_bloom.c プロジェクト: AlexOreshkevich/mongo
int
main(int argc, char *argv[])
{
	int ch;

	if ((g.progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		g.progname = argv[0];
	else
		++g.progname;

	/* Set default configuration values. */
	g.c_cache = 10;
	g.c_ops = 100000;
	g.c_key_max = 100;
	g.c_k = 8;
	g.c_factor = 16;
	g.c_srand = 3233456;

	/* Set values from the command line. */
	while ((ch = __wt_getopt(g.progname, argc, argv, "c:f:k:o:s:")) != EOF)
		switch (ch) {
		case 'c':			/* Cache size */
			g.c_cache = (u_int)atoi(__wt_optarg);
			break;
		case 'f':			/* Factor */
			g.c_factor = (u_int)atoi(__wt_optarg);
			break;
		case  'k':			/* Number of hash functions */
			g.c_k = (u_int)atoi(__wt_optarg);
			break;
		case 'o':			/* Number of ops */
			g.c_ops = (u_int)atoi(__wt_optarg);
			break;
		case 's':			/* Number of ops */
			g.c_srand = (u_int)atoi(__wt_optarg);
			break;
		default:
			usage();
		}

	argc -= __wt_optind;
	argv += __wt_optind;

	setup();
	run();
	cleanup();

	return (EXIT_SUCCESS);
}
コード例 #10
0
int
util_printlog(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	bool printable;

	printable = false;
	while ((ch = __wt_getopt(progname, argc, argv, "f:p")) != EOF)
		switch (ch) {
		case 'f':			/* output file */
			if (freopen(__wt_optarg, "w", stdout) == NULL) {
				fprintf(stderr, "%s: %s: reopen: %s\n",
				    progname, __wt_optarg, strerror(errno));
				return (1);
			}
			break;
		case 'p':
			printable = true;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* There should not be any more arguments. */
	if (argc != 0)
		return (usage());

	WT_UNUSED(printable);
	ret = __wt_txn_printlog(session, stdout);

	if (ret != 0) {
		fprintf(stderr, "%s: printlog failed: %s\n",
		    progname, session->strerror(session, ret));
		goto err;
	}

	if (0) {
err:		ret = 1;
	}
	return (ret);
}
コード例 #11
0
ファイル: util_list.c プロジェクト: 3rf/mongo
int
util_list(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int cflag, ch, vflag;
	char *name;

	cflag = vflag = 0;
	name = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "cv")) != EOF)
		switch (ch) {
		case 'c':
			cflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	switch (argc) {
	case 0:
		break;
	case 1:
		if ((name = util_name(*argv, "table")) == NULL)
			return (1);
		break;
	default:
		return (usage());
	}

	ret = list_print(session, name, cflag, vflag);

	if (name != NULL)
		free(name);

	return (ret);
}
コード例 #12
0
ファイル: util_salvage.c プロジェクト: ajdavis/mongo
int
util_salvage(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	const char *force;
	char *uri;

	force = NULL;
	uri = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "F")) != EOF)
		switch (ch) {
		case 'F':
			force = "force";
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining argument is the file name. */
	if (argc != 1)
		return (usage());
	if ((uri = util_uri(session, *argv, "file")) == NULL)
		return (1);

	if ((ret = session->salvage(session, uri, force)) != 0)
		(void)util_err(session, ret, "session.salvage: %s", uri);
	else {
		/*
		 * Verbose configures a progress counter, move to the next
		 * line.
		 */
		if (verbose)
			printf("\n");
	}

	free(uri);
	return (ret);
}
コード例 #13
0
int
util_rebalance(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char *name;

	name = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining argument is the table name. */
	if (argc != 1)
		return (usage());
	if ((name = util_name(session, *argv, "table")) == NULL)
		return (1);

	if ((ret = session->rebalance(session, name, NULL)) != 0) {
		fprintf(stderr, "%s: rebalance(%s): %s\n",
		    progname, name, session->strerror(session, ret));
		goto err;
	}

	/* Verbose configures a progress counter, move to the next line. */
	if (verbose)
		printf("\n");

	if (0) {
err:		ret = 1;
	}

	free(name);

	return (ret);
}
コード例 #14
0
int
util_rename(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char *uri, *newuri;

	uri = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining arguments are the object uri and new name. */
	if (argc != 2)
		return (usage());
	if ((uri = util_name(*argv, "table")) == NULL)
		return (1);
	newuri = argv[1];

	if ((ret = session->rename(session, uri, newuri, NULL)) != 0) {
		fprintf(stderr, "%s: rename %s to %s: %s\n",
		    progname, uri, newuri, wiredtiger_strerror(ret));
		goto err;
	}

	if (0) {
err:		ret = 1;
	}

	if (uri != NULL)
		free(uri);

	return (ret);
}
コード例 #15
0
ファイル: util_compact.c プロジェクト: 7segments/mongo-1
int
util_compact(WT_SESSION *session, int argc, char *argv[])
{
	WT_DECL_RET;
	int ch;
	char *uri;

	uri = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining argument is the table name. */
	if (argc != 1)
		return (usage());
	if ((uri = util_name(session, *argv, "table")) == NULL)
		return (1);

	if ((ret = session->compact(session, uri, NULL)) != 0) {
		fprintf(stderr, "%s: compact(%s): %s\n",
		    progname, uri, session->strerror(session, ret));
		goto err;
	}

	if (0) {
err:		ret = 1;
	}

	if (uri != NULL)
		free(uri);

	return (ret);
}
コード例 #16
0
ファイル: t.c プロジェクト: judahschvimer/mongo
int
main(int argc, char *argv[])
{
	time_t start;
	int ch, onerun, reps;
	const char *config, *home;

	config = NULL;

#ifdef _WIN32
	g.progname = "t_format.exe";
#else
	if ((g.progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		g.progname = argv[0];
	else
		++g.progname;
#endif

#if 0
	/* Configure the GNU malloc for debugging. */
	(void)setenv("MALLOC_CHECK_", "2", 1);
#endif
#if 0
	/* Configure the FreeBSD malloc for debugging. */
	(void)setenv("MALLOC_OPTIONS", "AJ", 1);
#endif

	/* Track progress unless we're re-directing output to a file. */
	g.c_quiet = isatty(1) ? 0 : 1;

	/* Set values from the command line. */
	home = NULL;
	onerun = 0;
	while ((ch = __wt_getopt(
	    g.progname, argc, argv, "1C:c:H:h:Llqrt:")) != EOF)
		switch (ch) {
		case '1':			/* One run */
			onerun = 1;
			break;
		case 'C':			/* wiredtiger_open config */
			g.config_open = __wt_optarg;
			break;
		case 'c':			/* Configuration from a file */
			config = __wt_optarg;
			break;
		case 'H':
			g.helium_mount = __wt_optarg;
			break;
		case 'h':
			home = __wt_optarg;
			break;
		case 'L':			/* Re-direct output to a log */
			/*
			 * The -l option is a superset of -L, ignore -L if we
			 * have already configured logging for operations.
			 */
			if (g.logging == 0)
				g.logging = LOG_FILE;
			break;
		case 'l':			/* Turn on operation logging */
			g.logging = LOG_OPS;
			break;
		case 'q':			/* Quiet */
			g.c_quiet = 1;
			break;
		case 'r':			/* Replay a run */
			g.replay = 1;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* Initialize the global RNG. */
	testutil_check(__wt_random_init_seed(NULL, &g.rnd));

	/* Set up paths. */
	path_setup(home);

	/* If it's a replay, use the home directory's CONFIG file. */
	if (g.replay) {
		if (config != NULL)
			testutil_die(EINVAL, "-c incompatible with -r");
		if (access(g.home_config, R_OK) != 0)
			testutil_die(ENOENT, "%s", g.home_config);
		config = g.home_config;
	}

	/*
	 * If we weren't given a configuration file, set values from "CONFIG",
	 * if it exists.
	 *
	 * Small hack to ignore any CONFIG file named ".", that just makes it
	 * possible to ignore any local CONFIG file, used when running checks.
	 */
	if (config == NULL && access("CONFIG", R_OK) == 0)
		config = "CONFIG";
	if (config != NULL && strcmp(config, ".") != 0)
		config_file(config);

	/*
	 * The rest of the arguments are individual configurations that modify
	 * the base configuration.
	 */
	for (; *argv != NULL; ++argv)
		config_single(*argv, 1);

	/*
	 * Multithreaded runs can be replayed: it's useful and we'll get the
	 * configuration correct.  Obviously the order of operations changes,
	 * warn the user.
	 */
	if (g.replay && !SINGLETHREADED)
		printf("Warning: replaying a threaded run\n");

	/*
	 * Single-threaded runs historically exited after a single replay, which
	 * makes sense when you're debugging, leave that semantic in place.
	 */
	if (g.replay && SINGLETHREADED)
		g.c_runs = 1;

	/*
	 * Let the command line -1 flag override runs configured from other
	 * sources.
	 */
	if (onerun)
		g.c_runs = 1;

	/*
	 * Initialize locks to single-thread named checkpoints and backups, last
	 * last-record updates, and failures.
	 */
	testutil_check(pthread_rwlock_init(&g.append_lock, NULL));
	testutil_check(pthread_rwlock_init(&g.backup_lock, NULL));
	testutil_check(pthread_rwlock_init(&g.checkpoint_lock, NULL));
	testutil_check(pthread_rwlock_init(&g.death_lock, NULL));

	printf("%s: process %" PRIdMAX "\n", g.progname, (intmax_t)getpid());
	while (++g.run_cnt <= g.c_runs || g.c_runs == 0 ) {
		startup();			/* Start a run */

		config_setup();			/* Run configuration */
		config_print(0);		/* Dump run configuration */
		key_len_setup();		/* Setup keys */

		start = time(NULL);
		track("starting up", 0ULL, NULL);

#ifdef HAVE_BERKELEY_DB
		if (SINGLETHREADED)
			bdb_open();		/* Initial file config */
#endif
		wts_open(g.home, true, &g.wts_conn);
		wts_init();

		wts_load();			/* Load initial records */
		wts_verify("post-bulk verify");	/* Verify */

		/*
		 * If we're not doing any operations, scan the bulk-load, copy
		 * the statistics and we're done. Otherwise, loop reading and
		 * operations, with a verify after each set.
		 */
		if (g.c_timer == 0 && g.c_ops == 0) {
			wts_read_scan();		/* Read scan */
			wts_stats();			/* Statistics */
		} else
			for (reps = 1; reps <= FORMAT_OPERATION_REPS; ++reps) {
				wts_read_scan();	/* Read scan */

							/* Operations */
				wts_ops(reps == FORMAT_OPERATION_REPS);

				/*
				 * Copy out the run's statistics after the last
				 * set of operations.
				 *
				 * XXX
				 * Verify closes the underlying handle and
				 * discards the statistics, read them first.
				 */
				if (reps == FORMAT_OPERATION_REPS)
					wts_stats();

							/* Verify */
				wts_verify("post-ops verify");
			}

		track("shutting down", 0ULL, NULL);
#ifdef HAVE_BERKELEY_DB
		if (SINGLETHREADED)
			bdb_close();
#endif
		wts_close();

		/*
		 * Rebalance testing.
		 */
		wts_rebalance();

		/*
		 * If single-threaded, we can dump and compare the WiredTiger
		 * and Berkeley DB data sets.
		 */
		if (SINGLETHREADED)
			wts_dump("standard", 1);

		/*
		 * Salvage testing.
		 */
		wts_salvage();

		/* Overwrite the progress line with a completion line. */
		if (!g.c_quiet)
			printf("\r%78s\r", " ");
		printf("%4d: %s, %s (%.0f seconds)\n",
		    g.run_cnt, g.c_data_source,
		    g.c_file_type, difftime(time(NULL), start));
		fflush(stdout);
	}

	/* Flush/close any logging information. */
	fclose_and_clear(&g.logfp);
	fclose_and_clear(&g.randfp);

	config_print(0);

	testutil_check(pthread_rwlock_destroy(&g.append_lock));
	testutil_check(pthread_rwlock_destroy(&g.backup_lock));
	testutil_check(pthread_rwlock_destroy(&g.checkpoint_lock));
	testutil_check(pthread_rwlock_destroy(&g.death_lock));

	config_clear();

	return (EXIT_SUCCESS);
}
コード例 #17
0
ファイル: util_dump.c プロジェクト: Tsmith5151/mongo
int
util_dump(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	size_t len;
	int ch, i;
	bool hex, json, reverse;
	char *checkpoint, *config, *name;

	hex = json = reverse = false;
	checkpoint = config = name = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "c:f:jrx")) != EOF)
		switch (ch) {
		case 'c':
			checkpoint = __wt_optarg;
			break;
		case 'f':			/* output file */
			if (freopen(__wt_optarg, "w", stdout) == NULL)
				return (util_err(
				    session, errno, "%s: reopen", __wt_optarg));
			break;
		case 'j':
			json = true;
			break;
		case 'r':
			reverse = true;
			break;
		case 'x':
			hex = true;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* -j and -x are incompatible. */
	if (hex && json) {
		fprintf(stderr,
		    "%s: the -j and -x dump options are incompatible\n",
		    progname);
		goto err;
	}

	/* The remaining argument is the uri. */
	if (argc < 1 || (argc != 1 && !json))
		return (usage());

	if (json &&
	    ((ret = dump_json_begin(session)) != 0 ||
	    (ret = dump_prefix(session, hex, json)) != 0))
		goto err;

	for (i = 0; i < argc; i++) {
		if (json && i > 0)
			if ((ret = dump_json_separator(session)) != 0)
				goto err;
		free(name);
		name = NULL;

		if ((name = util_name(session, argv[i], "table")) == NULL)
			goto err;

		if (dump_config(session, name, hex, json) != 0)
			goto err;

		len =
		    checkpoint == NULL ? 0 : strlen("checkpoint=") +
		    strlen(checkpoint) + 1;
		len += strlen(json ? "dump=json" :
		    (hex ? "dump=hex" : "dump=print"));
		if ((config = malloc(len + 10)) == NULL)
			goto err;
		if (checkpoint == NULL)
			config[0] = '\0';
		else {
			(void)strcpy(config, "checkpoint=");
			(void)strcat(config, checkpoint);
			(void)strcat(config, ",");
		}
		(void)strcat(config, json ? "dump=json" :
		    (hex ? "dump=hex" : "dump=print"));
		if ((ret = session->open_cursor(
		    session, name, NULL, config, &cursor)) != 0) {
			fprintf(stderr, "%s: cursor open(%s) failed: %s\n",
			    progname, name, session->strerror(session, ret));
			goto err;
		}

		if ((ret = dump_record(cursor, reverse, json)) != 0)
			goto err;
		if (json && (ret = dump_json_table_end(session)) != 0)
			goto err;
	}
	if (json && ((ret = dump_json_end(session)) != 0))
		goto err;

	if (0) {
err:		ret = 1;
	}

	free(config);
	free(name);

	return (ret);
}
コード例 #18
0
ファイル: timestamp-abort.c プロジェクト: DINKIN/mongo
int
main(int argc, char *argv[])
{
	struct stat sb;
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cur_coll, *cur_local, *cur_oplog, *cur_stable;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	pid_t pid;
	uint64_t absent_coll, absent_local, absent_oplog, count, key, last_key;
	uint64_t first_miss, middle_coll, middle_local, middle_oplog;
	uint64_t stable_fp, stable_val, val[MAX_TH+1];
	uint32_t i, nth, timeout;
	int ch, status, ret;
	const char *working_dir;
	char buf[512], fname[64], kname[64], statname[1024];
	bool fatal, rand_th, rand_time, verify_only;

	(void)testutil_set_progname(argv);

	compat = inmem = false;
	use_ts = true;
	nth = MIN_TH;
	rand_th = rand_time = true;
	timeout = MIN_TIME;
	verify_only = false;
	working_dir = "WT_TEST.timestamp-abort";

	while ((ch = __wt_getopt(progname, argc, argv, "Ch:mT:t:vz")) != EOF)
		switch (ch) {
		case 'C':
			compat = true;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 'm':
			inmem = true;
			break;
		case 'T':
			rand_th = false;
			nth = (uint32_t)atoi(__wt_optarg);
			break;
		case 't':
			rand_time = false;
			timeout = (uint32_t)atoi(__wt_optarg);
			break;
		case 'v':
			verify_only = true;
			break;
		case 'z':
			use_ts = false;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, sizeof(home), working_dir);
	/*
	 * If the user wants to verify they need to tell us how many threads
	 * there were so we can find the old record files.
	 */
	if (verify_only && rand_th) {
		fprintf(stderr,
		    "Verify option requires specifying number of threads\n");
		exit (EXIT_FAILURE);
	}
	if (!verify_only) {
		testutil_make_work_dir(home);

		__wt_random_init_seed(NULL, &rnd);
		if (rand_time) {
			timeout = __wt_random(&rnd) % MAX_TIME;
			if (timeout < MIN_TIME)
				timeout = MIN_TIME;
		}
		if (rand_th) {
			nth = __wt_random(&rnd) % MAX_TH;
			if (nth < MIN_TH)
				nth = MIN_TH;
		}
		printf("Parent: compatibility: %s, "
		    "in-mem log sync: %s, timestamp in use: %s\n",
		    compat ? "true" : "false",
		    inmem ? "true" : "false",
		    use_ts ? "true" : "false");
		printf("Parent: Create %" PRIu32
		    " threads; sleep %" PRIu32 " seconds\n", nth, timeout);
		/*
		 * Fork a child to insert as many items.  We will then randomly
		 * kill the child, run recovery and make sure all items we wrote
		 * exist after recovery runs.
		 */
		testutil_checksys((pid = fork()) < 0);

		if (pid == 0) { /* child */
			run_workload(nth);
			return (EXIT_SUCCESS);
		}

		/* parent */
		/*
		 * Sleep for the configured amount of time before killing
		 * the child.  Start the timeout from the time we notice that
		 * the file has been created.  That allows the test to run
		 * correctly on really slow machines.  Verify the process ID
		 * still exists in case the child aborts for some reason we
		 * don't stay in this loop forever.
		 */
		testutil_check(__wt_snprintf(
		    statname, sizeof(statname), "%s/%s", home, ckpt_file));
		while (stat(statname, &sb) != 0 && kill(pid, 0) == 0)
			sleep(1);
		sleep(timeout);

		/*
		 * !!! It should be plenty long enough to make sure more than
		 * one log file exists.  If wanted, that check would be added
		 * here.
		 */
		printf("Kill child\n");
		testutil_checksys(kill(pid, SIGKILL) != 0);
		testutil_checksys(waitpid(pid, &status, 0) == -1);
	}
	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	if (chdir(home) != 0)
		testutil_die(errno, "parent chdir: %s", home);
	testutil_check(__wt_snprintf(buf, sizeof(buf),
	    "rm -rf ../%s.SAVE && mkdir ../%s.SAVE && "
	    "cp -p WiredTigerLog.* ../%s.SAVE",
	     home, home, home));
	(void)system(buf);
	printf("Open database, run recovery and verify content\n");

	/*
	 * Open the connection which forces recovery to be run.
	 */
	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	/*
	 * Open a cursor on all the tables.
	 */
	if ((ret = session->open_cursor(session,
	    uri_collection, NULL, NULL, &cur_coll)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri_collection);
	if ((ret = session->open_cursor(session,
	    uri_local, NULL, NULL, &cur_local)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri_local);
	if ((ret = session->open_cursor(session,
	    uri_oplog, NULL, NULL, &cur_oplog)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri_oplog);
	if ((ret = session->open_cursor(session,
	    stable_store, NULL, NULL, &cur_stable)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", stable_store);

	/*
	 * Find the biggest stable timestamp value that was saved.
	 */
	stable_val = 0;
	memset(val, 0, sizeof(val));
	while (cur_stable->next(cur_stable) == 0) {
		cur_stable->get_key(cur_stable, &key);
		cur_stable->get_value(cur_stable, &val[key]);
		if (val[key] > stable_val)
			stable_val = val[key];

		if (use_ts)
			printf("Stable: key %" PRIu64 " value %" PRIu64 "\n",
			    key, val[key]);
	}
	if (use_ts)
		printf("Got stable_val %" PRIu64 "\n", stable_val);

	count = 0;
	absent_coll = absent_local = absent_oplog = 0;
	fatal = false;
	for (i = 1; i <= nth; ++i) {
		first_miss = middle_coll = middle_local = middle_oplog = 0;
		testutil_check(__wt_snprintf(
		    fname, sizeof(fname), RECORDS_FILE, i));
		if ((fp = fopen(fname, "r")) == NULL)
			testutil_die(errno, "fopen: %s", fname);

		/*
		 * For every key in the saved file, verify that the key exists
		 * in the table after recovery.  If we're doing in-memory
		 * log buffering we never expect a record missing in the middle,
		 * but records may be missing at the end.  If we did
		 * write-no-sync, we expect every key to have been recovered.
		 */
		for (last_key = UINT64_MAX;; ++count, last_key = key) {
			ret = fscanf(fp, "%" SCNu64 "%" SCNu64 "\n",
			    &stable_fp, &key);
			if (ret != EOF && ret != 2) {
				/*
				 * If we find a partial line, consider it
				 * like an EOF.
				 */
				if (ret == 1 || ret == 0)
					break;
				testutil_die(errno, "fscanf");
			}
			if (ret == EOF)
				break;
			/*
			 * If we're unlucky, the last line may be a partially
			 * written key at the end that can result in a false
			 * negative error for a missing record.  Detect it.
			 */
			if (last_key != UINT64_MAX && key != last_key + 1) {
				printf("%s: Ignore partial record %" PRIu64
				    " last valid key %" PRIu64 "\n",
				    fname, key, last_key);
				break;
			}
			testutil_check(__wt_snprintf(
			    kname, sizeof(kname), "%" PRIu64, key));
			cur_coll->set_key(cur_coll, kname);
			cur_local->set_key(cur_local, kname);
			cur_oplog->set_key(cur_oplog, kname);
			/*
			 * The collection table should always only have the
			 * data as of the checkpoint.
			 */
			if ((ret = cur_coll->search(cur_coll)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				/*
				 * If we don't find a record, the stable
				 * timestamp written to our file better be
				 * larger than the saved one.
				 */
				if (!inmem &&
				    stable_fp != 0 && stable_fp <= val[i]) {
					printf("%s: COLLECTION no record with "
					    "key %" PRIu64 " record ts %" PRIu64
					    " <= stable ts %" PRIu64 "\n",
					    fname, key, stable_fp, val[i]);
					absent_coll++;
				}
				if (middle_coll == 0)
					first_miss = key;
				middle_coll = key;
			} else if (middle_coll != 0) {
				/*
				 * We should never find an existing key after
				 * we have detected one missing.
				 */
				printf("%s: COLLECTION after absent records %"
				    PRIu64 "-%" PRIu64 " key %" PRIu64
				    " exists\n",
				    fname, first_miss, middle_coll, key);
				fatal = true;
			}
			/*
			 * The local table should always have all data.
			 */
			if ((ret = cur_local->search(cur_local)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				if (!inmem)
					printf("%s: LOCAL no record with key %"
					    PRIu64 "\n", fname, key);
				absent_local++;
				middle_local = key;
			} else if (middle_local != 0) {
				/*
				 * We should never find an existing key after
				 * we have detected one missing.
				 */
				printf("%s: LOCAL after absent record at %"
				    PRIu64 " key %" PRIu64 " exists\n",
				    fname, middle_local, key);
				fatal = true;
			}
			/*
			 * The oplog table should always have all data.
			 */
			if ((ret = cur_oplog->search(cur_oplog)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				if (!inmem)
					printf("%s: OPLOG no record with key %"
					    PRIu64 "\n", fname, key);
				absent_oplog++;
				middle_oplog = key;
			} else if (middle_oplog != 0) {
				/*
				 * We should never find an existing key after
				 * we have detected one missing.
				 */
				printf("%s: OPLOG after absent record at %"
				    PRIu64 " key %" PRIu64 " exists\n",
				    fname, middle_oplog, key);
				fatal = true;
			}
		}
		testutil_checksys(fclose(fp) != 0);
	}
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if (fatal)
		return (EXIT_FAILURE);
	if (!inmem && absent_coll) {
		printf("COLLECTION: %" PRIu64
		    " record(s) absent from %" PRIu64 "\n",
		    absent_coll, count);
		fatal = true;
	}
	if (!inmem && absent_local) {
		printf("LOCAL: %" PRIu64 " record(s) absent from %" PRIu64 "\n",
		    absent_local, count);
		fatal = true;
	}
	if (!inmem && absent_oplog) {
		printf("OPLOG: %" PRIu64 " record(s) absent from %" PRIu64 "\n",
		    absent_oplog, count);
		fatal = true;
	}
	if (fatal)
		return (EXIT_FAILURE);
	printf("%" PRIu64 " records verified\n", count);
	return (EXIT_SUCCESS);
}
コード例 #19
0
ファイル: test_checkpoint.c プロジェクト: Arikes/mongo
int
main(int argc, char *argv[])
{
	table_type ttype;
	int ch, cnt, ret, runs;
	char *working_dir;
	const char *config_open;

	if ((g.progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		g.progname = argv[0];
	else
		++g.progname;

	config_open = NULL;
	ret = 0;
	working_dir = NULL;
	ttype = MIX;
	g.checkpoint_name = "WiredTigerCheckpoint";
	if ((g.home = malloc(512)) == NULL)
		testutil_die(ENOMEM, "Unable to allocate memory");
	g.nkeys = 10000;
	g.nops = 100000;
	g.ntables = 3;
	g.nworkers = 1;
	runs = 1;

	while ((ch = __wt_getopt(
	    g.progname, argc, argv, "c:C:h:k:l:n:r:t:T:W:")) != EOF)
		switch (ch) {
		case 'c':
			g.checkpoint_name = __wt_optarg;
			break;
		case 'C':			/* wiredtiger_open config */
			config_open = __wt_optarg;
			break;
		case 'h':			/* wiredtiger_open config */
			working_dir = __wt_optarg;
			break;
		case 'k':			/* rows */
			g.nkeys = (u_int)atoi(__wt_optarg);
			break;
		case 'l':			/* log */
			if ((g.logfp = fopen(__wt_optarg, "w")) == NULL) {
				fprintf(stderr,
				    "%s: %s\n", __wt_optarg, strerror(errno));
				return (EXIT_FAILURE);
			}
			break;
		case 'n':			/* operations */
			g.nops = (u_int)atoi(__wt_optarg);
			break;
		case 'r':			/* runs */
			runs = atoi(__wt_optarg);
			break;
		case 't':
			switch (__wt_optarg[0]) {
			case 'c':
				ttype = COL;
				break;
			case 'l':
				ttype = LSM;
				break;
			case 'm':
				ttype = MIX;
				break;
			case 'r':
				ttype = ROW;
				break;
			default:
				return (usage());
			}
			break;
		case 'T':
			g.ntables = atoi(__wt_optarg);
			break;
		case 'W':
			g.nworkers = atoi(__wt_optarg);
			break;
		default:
			return (usage());
		}

	argc -= __wt_optind;
	if (argc != 0)
		return (usage());

	/* Clean up on signal. */
	(void)signal(SIGINT, onint);

	testutil_work_dir_from_path(g.home, 512, working_dir);

	printf("%s: process %" PRIu64 "\n", g.progname, (uint64_t)getpid());
	for (cnt = 1; (runs == 0 || cnt <= runs) && g.status == 0; ++cnt) {
		printf("    %d: %u workers, %u tables\n",
		    cnt, g.nworkers, g.ntables);

		(void)cleanup();		/* Clean up previous runs */

		/* Setup a fresh set of cookies in the global array. */
		if ((g.cookies = calloc(
		    (size_t)(g.ntables), sizeof(COOKIE))) == NULL) {
			(void)log_print_err("No memory", ENOMEM, 1);
			break;
		}

		g.running = 1;

		if ((ret = wt_connect(config_open)) != 0) {
			(void)log_print_err("Connection failed", ret, 1);
			break;
		}

		if ((ret = start_checkpoints()) != 0) {
			(void)log_print_err("Start checkpoints failed", ret, 1);
			break;
		}
		if ((ret = start_workers(ttype)) != 0) {
			(void)log_print_err("Start workers failed", ret, 1);
			break;
		}

		g.running = 0;
		if ((ret = end_checkpoints()) != 0) {
			(void)log_print_err("Start workers failed", ret, 1);
			break;
		}

		free(g.cookies);
		g.cookies = NULL;
		if ((ret = wt_shutdown()) != 0) {
			(void)log_print_err("Start workers failed", ret, 1);
			break;
		}
	}
	if (g.logfp != NULL)
		(void)fclose(g.logfp);

	/* Ensure that cleanup is done on error. */
	(void)wt_shutdown();
	free(g.cookies);
	return (g.status);
}
コード例 #20
0
ファイル: util_stat.c プロジェクト: Machyne/mongo
int
util_stat(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	size_t urilen;
	int ch;
	bool objname_free;
	const char *config, *pval, *desc;
	char *objname, *uri;

	objname_free = false;
	objname = uri = NULL;
	config = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "af")) != EOF)
		switch (ch) {
		case 'a':
			/*
			 * Historically, the -a option meant include all of the
			 * statistics; because we are opening the database with
			 * statistics=(all), that is now the default, allow the
			 * option for compatibility.
			 */
			config = NULL;
			break;
		case 'f':
			config = "statistics=(fast)";
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/*
	 * If there are no arguments, the statistics cursor operates on the
	 * connection, otherwise, the optional remaining argument is a file
	 * or LSM name.
	 */
	switch (argc) {
	case 0:
		objname = (char *)"";
		break;
	case 1:
		if ((objname = util_name(session, *argv, "table")) == NULL)
			return (1);
		objname_free = true;
		break;
	default:
		return (usage());
	}

	urilen = strlen("statistics:") + strlen(objname) + 1;
	if ((uri = calloc(urilen, 1)) == NULL) {
		fprintf(stderr, "%s: %s\n", progname, strerror(errno));
		goto err;
	}
	snprintf(uri, urilen, "statistics:%s", objname);

	if ((ret =
	    session->open_cursor(session, uri, NULL, config, &cursor)) != 0) {
		fprintf(stderr, "%s: cursor open(%s) failed: %s\n",
		    progname, uri, session->strerror(session, ret));
		goto err;
	}

	/* List the statistics. */
	while (
	    (ret = cursor->next(cursor)) == 0 &&
	    (ret = cursor->get_value(cursor, &desc, &pval, NULL)) == 0)
		if (printf("%s=%s\n", desc, pval) < 0) {
			ret = errno;
			break;
		}
	if (ret == WT_NOTFOUND)
		ret = 0;

	if (ret != 0) {
		fprintf(stderr, "%s: cursor get(%s) failed: %s\n",
		    progname, objname, session->strerror(session, ret));
		goto err;
	}

	if (0) {
err:		ret = 1;
	}
	if (objname_free)
		free(objname);
	free(uri);

	return (ret);
}
コード例 #21
0
int
main(int argc, char *argv[])
{
	struct sigaction sa;
	struct stat sb;
	FILE *fp;
	REPORT c_rep[MAX_TH], l_rep[MAX_TH], o_rep[MAX_TH];
	WT_CONNECTION *conn;
	WT_CURSOR *cur_coll, *cur_local, *cur_oplog;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	pid_t pid;
	uint64_t absent_coll, absent_local, absent_oplog, count, key, last_key;
	uint64_t stable_fp, stable_val;
	uint32_t i, nth, timeout;
	int ch, status, ret;
	const char *working_dir;
	char buf[512], fname[64], kname[64], statname[1024];
	char ts_string[WT_TS_HEX_STRING_SIZE];
	bool fatal, rand_th, rand_time, verify_only;

	(void)testutil_set_progname(argv);

	compat = inmem = false;
	use_ts = true;
	nth = MIN_TH;
	rand_th = rand_time = true;
	timeout = MIN_TIME;
	verify_only = false;
	working_dir = "WT_TEST.timestamp-abort";

	while ((ch = __wt_getopt(progname, argc, argv, "Ch:LmT:t:vz")) != EOF)
		switch (ch) {
		case 'C':
			compat = true;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 'L':
			table_pfx = "lsm";
			break;
		case 'm':
			inmem = true;
			break;
		case 'T':
			rand_th = false;
			nth = (uint32_t)atoi(__wt_optarg);
			if (nth > MAX_TH) {
				fprintf(stderr,
				    "Number of threads is larger than the"
				    " maximum %" PRId32 "\n", MAX_TH);
				return (EXIT_FAILURE);
			}
			break;
		case 't':
			rand_time = false;
			timeout = (uint32_t)atoi(__wt_optarg);
			break;
		case 'v':
			verify_only = true;
			break;
		case 'z':
			use_ts = false;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, sizeof(home), working_dir);
	testutil_check(pthread_rwlock_init(&ts_lock, NULL));

	/*
	 * If the user wants to verify they need to tell us how many threads
	 * there were so we can find the old record files.
	 */
	if (verify_only && rand_th) {
		fprintf(stderr,
		    "Verify option requires specifying number of threads\n");
		exit (EXIT_FAILURE);
	}
	if (!verify_only) {
		testutil_make_work_dir(home);

		__wt_random_init_seed(NULL, &rnd);
		if (rand_time) {
			timeout = __wt_random(&rnd) % MAX_TIME;
			if (timeout < MIN_TIME)
				timeout = MIN_TIME;
		}
		if (rand_th) {
			nth = __wt_random(&rnd) % MAX_TH;
			if (nth < MIN_TH)
				nth = MIN_TH;
		}

		printf("Parent: compatibility: %s, "
		    "in-mem log sync: %s, timestamp in use: %s\n",
		    compat ? "true" : "false",
		    inmem ? "true" : "false",
		    use_ts ? "true" : "false");
		printf("Parent: Create %" PRIu32
		    " threads; sleep %" PRIu32 " seconds\n", nth, timeout);
		printf("CONFIG: %s%s%s%s -h %s -T %" PRIu32 " -t %" PRIu32 "\n",
		    progname,
		    compat ? " -C" : "",
		    inmem ? " -m" : "",
		    !use_ts ? " -z" : "",
		    working_dir, nth, timeout);
		/*
		 * Fork a child to insert as many items.  We will then randomly
		 * kill the child, run recovery and make sure all items we wrote
		 * exist after recovery runs.
		 */
		memset(&sa, 0, sizeof(sa));
		sa.sa_handler = handler;
		testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
		testutil_checksys((pid = fork()) < 0);

		if (pid == 0) { /* child */
			run_workload(nth);
			return (EXIT_SUCCESS);
		}

		/* parent */
		/*
		 * Sleep for the configured amount of time before killing
		 * the child.  Start the timeout from the time we notice that
		 * the file has been created.  That allows the test to run
		 * correctly on really slow machines.
		 */
		testutil_check(__wt_snprintf(
		    statname, sizeof(statname), "%s/%s", home, ckpt_file));
		while (stat(statname, &sb) != 0)
			testutil_sleep_wait(1, pid);
		sleep(timeout);
		sa.sa_handler = SIG_DFL;
		testutil_checksys(sigaction(SIGCHLD, &sa, NULL));

		/*
		 * !!! It should be plenty long enough to make sure more than
		 * one log file exists.  If wanted, that check would be added
		 * here.
		 */
		printf("Kill child\n");
		testutil_checksys(kill(pid, SIGKILL) != 0);
		testutil_checksys(waitpid(pid, &status, 0) == -1);
	}
	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it. Don't do it all the time because
	 * it can use a lot of disk space, which can cause test machine
	 * issues.
	 */
	if (chdir(home) != 0)
		testutil_die(errno, "parent chdir: %s", home);
	/*
	 * The tables can get very large, so while we'd ideally like to
	 * copy the entire database, we only copy the log files for now.
	 * Otherwise it can take far too long to run the test, particularly
	 * in automated testing.
	 */
	testutil_check(__wt_snprintf(buf, sizeof(buf),
	    "rm -rf ../%s.SAVE && mkdir ../%s.SAVE && "
	    "cp -p * ../%s.SAVE",
	     home, home, home));
	if ((status = system(buf)) < 0)
		testutil_die(status, "system: %s", buf);
	printf("Open database, run recovery and verify content\n");

	/*
	 * Open the connection which forces recovery to be run.
	 */
	testutil_check(wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn));
	testutil_check(conn->open_session(conn, NULL, NULL, &session));
	/*
	 * Open a cursor on all the tables.
	 */
	testutil_check(__wt_snprintf(
	    buf, sizeof(buf), "%s:%s", table_pfx, uri_collection));
	testutil_check(session->open_cursor(session,
	    buf, NULL, NULL, &cur_coll));
	testutil_check(__wt_snprintf(
	    buf, sizeof(buf), "%s:%s", table_pfx, uri_local));
	testutil_check(session->open_cursor(session,
	    buf, NULL, NULL, &cur_local));
	testutil_check(__wt_snprintf(
	    buf, sizeof(buf), "%s:%s", table_pfx, uri_oplog));
	testutil_check(session->open_cursor(session,
	    buf, NULL, NULL, &cur_oplog));

	/*
	 * Find the biggest stable timestamp value that was saved.
	 */
	stable_val = 0;
	if (use_ts) {
		testutil_check(
		    conn->query_timestamp(conn, ts_string, "get=recovery"));
		testutil_assert(
		    sscanf(ts_string, "%" SCNx64, &stable_val) == 1);
		printf("Got stable_val %" PRIu64 "\n", stable_val);
	}

	count = 0;
	absent_coll = absent_local = absent_oplog = 0;
	fatal = false;
	for (i = 0; i < nth; ++i) {
		initialize_rep(&c_rep[i]);
		initialize_rep(&l_rep[i]);
		initialize_rep(&o_rep[i]);
		testutil_check(__wt_snprintf(
		    fname, sizeof(fname), RECORDS_FILE, i));
		if ((fp = fopen(fname, "r")) == NULL)
			testutil_die(errno, "fopen: %s", fname);

		/*
		 * For every key in the saved file, verify that the key exists
		 * in the table after recovery.  If we're doing in-memory
		 * log buffering we never expect a record missing in the middle,
		 * but records may be missing at the end.  If we did
		 * write-no-sync, we expect every key to have been recovered.
		 */
		for (last_key = INVALID_KEY;; ++count, last_key = key) {
			ret = fscanf(fp, "%" SCNu64 "%" SCNu64 "\n",
			    &stable_fp, &key);
			if (last_key == INVALID_KEY) {
				c_rep[i].first_key = key;
				l_rep[i].first_key = key;
				o_rep[i].first_key = key;
			}
			if (ret != EOF && ret != 2) {
				/*
				 * If we find a partial line, consider it
				 * like an EOF.
				 */
				if (ret == 1 || ret == 0)
					break;
				testutil_die(errno, "fscanf");
			}
			if (ret == EOF)
				break;
			/*
			 * If we're unlucky, the last line may be a partially
			 * written key at the end that can result in a false
			 * negative error for a missing record.  Detect it.
			 */
			if (last_key != INVALID_KEY && key != last_key + 1) {
				printf("%s: Ignore partial record %" PRIu64
				    " last valid key %" PRIu64 "\n",
				    fname, key, last_key);
				break;
			}
			testutil_check(__wt_snprintf(
			    kname, sizeof(kname), "%" PRIu64, key));
			cur_coll->set_key(cur_coll, kname);
			cur_local->set_key(cur_local, kname);
			cur_oplog->set_key(cur_oplog, kname);
			/*
			 * The collection table should always only have the
			 * data as of the checkpoint.
			 */
			if ((ret = cur_coll->search(cur_coll)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				/*
				 * If we don't find a record, the stable
				 * timestamp written to our file better be
				 * larger than the saved one.
				 */
				if (!inmem &&
				    stable_fp != 0 && stable_fp <= stable_val) {
					printf("%s: COLLECTION no record with "
					    "key %" PRIu64 " record ts %" PRIu64
					    " <= stable ts %" PRIu64 "\n",
					    fname, key, stable_fp, stable_val);
					absent_coll++;
				}
				if (c_rep[i].first_miss == INVALID_KEY)
					c_rep[i].first_miss = key;
				c_rep[i].absent_key = key;
			} else if (c_rep[i].absent_key != INVALID_KEY &&
			    c_rep[i].exist_key == INVALID_KEY) {
				/*
				 * If we get here we found a record that exists
				 * after absent records, a hole in our data.
				 */
				c_rep[i].exist_key = key;
				fatal = true;
			} else if (!inmem &&
			    stable_fp != 0 && stable_fp > stable_val) {
				/*
				 * If we found a record, the stable timestamp
				 * written to our file better be no larger
				 * than the checkpoint one.
				 */
				printf("%s: COLLECTION record with "
				    "key %" PRIu64 " record ts %" PRIu64
				    " > stable ts %" PRIu64 "\n",
				    fname, key, stable_fp, stable_val);
				fatal = true;
			}
			/*
			 * The local table should always have all data.
			 */
			if ((ret = cur_local->search(cur_local)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				if (!inmem)
					printf("%s: LOCAL no record with key %"
					    PRIu64 "\n", fname, key);
				absent_local++;
				if (l_rep[i].first_miss == INVALID_KEY)
					l_rep[i].first_miss = key;
				l_rep[i].absent_key = key;
			} else if (l_rep[i].absent_key != INVALID_KEY &&
			    l_rep[i].exist_key == INVALID_KEY) {
				/*
				 * We should never find an existing key after
				 * we have detected one missing.
				 */
				l_rep[i].exist_key = key;
				fatal = true;
			}
			/*
			 * The oplog table should always have all data.
			 */
			if ((ret = cur_oplog->search(cur_oplog)) != 0) {
				if (ret != WT_NOTFOUND)
					testutil_die(ret, "search");
				if (!inmem)
					printf("%s: OPLOG no record with key %"
					    PRIu64 "\n", fname, key);
				absent_oplog++;
				if (o_rep[i].first_miss == INVALID_KEY)
					o_rep[i].first_miss = key;
				o_rep[i].absent_key = key;
			} else if (o_rep[i].absent_key != INVALID_KEY &&
			    o_rep[i].exist_key == INVALID_KEY) {
				/*
				 * We should never find an existing key after
				 * we have detected one missing.
				 */
				o_rep[i].exist_key = key;
				fatal = true;
			}
		}
		c_rep[i].last_key = last_key;
		l_rep[i].last_key = last_key;
		o_rep[i].last_key = last_key;
		testutil_checksys(fclose(fp) != 0);
		print_missing(&c_rep[i], fname, "COLLECTION");
		print_missing(&l_rep[i], fname, "LOCAL");
		print_missing(&o_rep[i], fname, "OPLOG");
	}
	testutil_check(conn->close(conn, NULL));
	if (!inmem && absent_coll) {
		printf("COLLECTION: %" PRIu64
		    " record(s) absent from %" PRIu64 "\n",
		    absent_coll, count);
		fatal = true;
	}
	if (!inmem && absent_local) {
		printf("LOCAL: %" PRIu64 " record(s) absent from %" PRIu64 "\n",
		    absent_local, count);
		fatal = true;
	}
	if (!inmem && absent_oplog) {
		printf("OPLOG: %" PRIu64 " record(s) absent from %" PRIu64 "\n",
		    absent_oplog, count);
		fatal = true;
	}
	testutil_check(pthread_rwlock_destroy(&ts_lock));
	if (fatal)
		return (EXIT_FAILURE);
	printf("%" PRIu64 " records verified\n", count);
	return (EXIT_SUCCESS);
}
コード例 #22
0
ファイル: recovery.c プロジェクト: Zhangwusheng/wiredtiger
int
main(int argc, char *argv[])
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	WT_RAND_STATE rnd;
	uint64_t key;
	uint32_t absent, count, timeout;
	int ch, status, ret;
	pid_t pid;
	char *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	working_dir = NULL;
	timeout = 10;
	while ((ch = __wt_getopt(progname, argc, argv, "h:t:")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 't':
			timeout = (uint32_t)atoi(__wt_optarg);
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, 512, working_dir);
	testutil_make_work_dir(home);

	/*
	 * Fork a child to insert as many items.  We will then randomly
	 * kill the child, run recovery and make sure all items we wrote
	 * exist after recovery runs.
	 */
	if ((pid = fork()) < 0)
		testutil_die(errno, "fork");

	if (pid == 0) { /* child */
		fill_db();
		return (EXIT_SUCCESS);
	}

	/* parent */
	__wt_random_init(&rnd);
	/* Sleep for the configured amount of time before killing the child. */
	printf("Parent: sleep %" PRIu32 " seconds, then kill child\n", timeout);
	sleep(timeout);

	/*
	 * !!! It should be plenty long enough to make sure more than one
	 * log file exists.  If wanted, that check would be added here.
	 */
	printf("Kill child\n");
	if (kill(pid, SIGKILL) != 0)
		testutil_die(errno, "kill");
	waitpid(pid, &status, 0);

	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	chdir(home);
	printf("Open database, run recovery and verify content\n");
	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	if ((fp = fopen(RECORDS_FILE, "r")) == NULL)
		testutil_die(errno, "fopen");

	/*
	 * For every key in the saved file, verify that the key exists
	 * in the table after recovery.  Since we did write-no-sync, we
	 * expect every key to have been recovered.
	 */
	for (absent = count = 0;; ++count) {
		ret = fscanf(fp, "%" SCNu64 "\n", &key);
		if (ret != EOF && ret != 1)
			testutil_die(errno, "fscanf");
		if (ret == EOF)
			break;
		cursor->set_key(cursor, key);
		if ((ret = cursor->search(cursor)) != 0) {
			if (ret != WT_NOTFOUND)
				testutil_die(ret, "search");
			printf("no record with key %" PRIu64 "\n", key);
			++absent;
		}
	}
	fclose(fp);
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if (absent) {
		printf("%u record(s) absent from %u\n", absent, count);
		return (EXIT_FAILURE);
	}
	printf("%u records verified\n", count);
	return (EXIT_SUCCESS);
}
コード例 #23
0
ファイル: util_write.c プロジェクト: 7segments/mongo-1
int
util_write(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	uint64_t recno;
	int append, ch, overwrite, rkey;
	const char *uri;
	char config[100];

	append = overwrite = 0;
	while ((ch = __wt_getopt(progname, argc, argv, "ao")) != EOF)
		switch (ch) {
		case 'a':
			append = 1;
			break;
		case 'o':
			overwrite = 1;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/*
	 * The remaining arguments are a uri followed by a list of values (if
	 * append is set), or key/value pairs (if append is not set).
	 */
	if (append) {
		if (argc < 2)
			return (usage());
	} else
		if (argc < 3 || ((argc - 1) % 2 != 0))
			return (usage());
	if ((uri = util_name(session, *argv, "table")) == NULL)
		return (1);

	/* Open the object. */
	(void)snprintf(config, sizeof(config), "%s,%s",
	    append ? "append=true" : "", overwrite ? "overwrite=true" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0)
		return (util_err(session, ret, "%s: session.open", uri));

	/*
	 * A simple search only makes sense if the key format is a string or a
	 * record number, and the value format is a single string.
	 */
	if (strcmp(cursor->key_format, "r") != 0 &&
	    strcmp(cursor->key_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the key format is "
		    "a record number or string\n",
		    progname);
		return (1);
	}
	rkey = strcmp(cursor->key_format, "r") == 0 ? 1 : 0;
	if (strcmp(cursor->value_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the value format is "
		    "a string\n",
		    progname);
		return (1);
	}

	/* Run through the values or key/value pairs. */
	while (*++argv != NULL) {
		if (!append) {
			if (rkey) {
				if (util_str2recno(session, *argv, &recno))
					return (1);
				cursor->set_key(cursor, recno);
			} else
				cursor->set_key(cursor, *argv);
			++argv;
		}
		cursor->set_value(cursor, *argv);

		if ((ret = cursor->insert(cursor)) != 0)
			return (util_cerr(cursor, "search", ret));
	}

	return (0);
}
コード例 #24
0
ファイル: truncated-log.c プロジェクト: BobbWu/wiredtiger
int
main(int argc, char *argv[])
{
	FILE *fp;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	uint64_t new_offset, offset;
	uint32_t count, max_key;
	int ch, status, ret;
	pid_t pid;
	const char *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	working_dir = "WT_TEST.truncated-log";
	while ((ch = __wt_getopt(progname, argc, argv, "h:")) != EOF)
		switch (ch) {
		case 'h':
			working_dir = __wt_optarg;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	testutil_work_dir_from_path(home, 512, working_dir);
	testutil_make_work_dir(home);

	/*
	 * Fork a child to insert as many items.  We will then randomly
	 * kill the child, run recovery and make sure all items we wrote
	 * exist after recovery runs.
	 */
	if ((pid = fork()) < 0)
		testutil_die(errno, "fork");

	if (pid == 0) { /* child */
		fill_db();
		return (EXIT_SUCCESS);
	}

	/* parent */
	/* Wait for child to kill itself. */
	if (waitpid(pid, &status, 0) == -1)
		testutil_die(errno, "waitpid");

	/*
	 * !!! If we wanted to take a copy of the directory before recovery,
	 * this is the place to do it.
	 */
	if (chdir(home) != 0)
		testutil_die(errno, "chdir: %s", home);

	printf("Open database, run recovery and verify content\n");
	if ((fp = fopen(RECORDS_FILE, "r")) == NULL)
		testutil_die(errno, "fopen");
	ret = fscanf(fp, "%" SCNu64 " %" SCNu32 "\n", &offset, &max_key);
	if (ret != 2)
		testutil_die(errno, "fscanf");
	if (fclose(fp) != 0)
		testutil_die(errno, "fclose");
	/*
	 * The offset is the beginning of the last record.  Truncate to
	 * the middle of that last record (i.e. ahead of that offset).
	 */
	if (offset > UINT64_MAX - V_SIZE)
		testutil_die(ERANGE, "offset");
	new_offset = offset + V_SIZE;
	printf("Parent: Truncate to %" PRIu64 "\n", new_offset);
	if ((ret = truncate(LOG_FILE_1, (wt_off_t)new_offset)) != 0)
		testutil_die(errno, "truncate");

	if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	/*
	 * For every key in the saved file, verify that the key exists
	 * in the table after recovery.  Since we did write-no-sync, we
	 * expect every key to have been recovered.
	 */
	count = 0;
	while ((ret = cursor->next(cursor)) == 0)
		++count;
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if (count > max_key) {
		printf("expected %" PRIu32 " records found %" PRIu32 "\n",
		    max_key, count);
		return (EXIT_FAILURE);
	}
	printf("%" PRIu32 " records verified\n", count);
	return (EXIT_SUCCESS);
}
コード例 #25
0
ファイル: t.c プロジェクト: ChineseDr/mongo
int
main(int argc, char *argv[])
{
	u_int readers, writers;
	int ch, cnt, runs;
	char *config_open, *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	config_open = NULL;
	working_dir = NULL;
	ftype = ROW;
	log_print = 0;
	multiple_files = 0;
	nkeys = 1000;
	max_nops = 10000;
	readers = 10;
	runs = 1;
	session_per_op = 0;
	vary_nops = 0;
	writers = 10;

	while ((ch = __wt_getopt(
	    progname, argc, argv, "C:Fk:h:Ll:n:R:r:St:vW:")) != EOF)
		switch (ch) {
		case 'C':			/* wiredtiger_open config */
			config_open = __wt_optarg;
			break;
		case 'F':			/* multiple files */
			multiple_files = 1;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 'k':			/* rows */
			nkeys = (u_int)atoi(__wt_optarg);
			break;
		case 'L':			/* log print per operation */
			log_print = 1;
			break;
		case 'l':			/* log */
			if ((logfp = fopen(__wt_optarg, "w")) == NULL) {
				fprintf(stderr,
				    "%s: %s\n", __wt_optarg, strerror(errno));
				return (EXIT_FAILURE);
			}
			break;
		case 'n':			/* operations */
			max_nops = (u_int)atoi(__wt_optarg);
			break;
		case 'R':
			readers = (u_int)atoi(__wt_optarg);
			break;
		case 'r':			/* runs */
			runs = atoi(__wt_optarg);
			break;
		case 'S':			/* new session per operation */
			session_per_op = 1;
			break;
		case 't':
			switch (__wt_optarg[0]) {
			case 'f':
				ftype = FIX;
				break;
			case 'r':
				ftype = ROW;
				break;
			case 'v':
				ftype = VAR;
				break;
			default:
				return (usage());
			}
			break;
		case 'v':			/* vary operation count */
			vary_nops = 1;
			break;
		case 'W':
			writers = (u_int)atoi(__wt_optarg);
			break;
		default:
			return (usage());
		}

	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		return (usage());

	testutil_work_dir_from_path(home, 512, working_dir);

	if (vary_nops && !multiple_files) {
		fprintf(stderr,
		    "Variable op counts only supported with multiple tables\n");
		return (usage());
	}

	/* Clean up on signal. */
	(void)signal(SIGINT, onint);

	printf("%s: process %" PRIu64 "\n", progname, (uint64_t)getpid());
	for (cnt = 1; runs == 0 || cnt <= runs; ++cnt) {
		printf(
		    "    %d: %u readers, %u writers\n", cnt, readers, writers);

		shutdown();			/* Clean up previous runs */

		wt_connect(config_open);	/* WiredTiger connection */

		if (rw_start(readers, writers))	/* Loop operations */
			return (EXIT_FAILURE);

		stats();			/* Statistics */

		wt_shutdown();			/* WiredTiger shut down */
	}
	return (0);
}
コード例 #26
0
ファイル: util_read.c プロジェクト: DINKIN/mongo
int
util_read(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	uint64_t recno;
	int ch;
	bool rkey, rval;
	char *uri, *value;

	uri = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining arguments are a uri followed by a list of keys. */
	if (argc < 2)
		return (usage());
	if ((uri = util_uri(session, *argv, "table")) == NULL)
		return (1);

	/*
	 * Open the object; free allocated memory immediately to simplify
	 * future error handling.
	 */
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		(void)util_err(session, ret, "%s: session.open_cursor", uri);
	free(uri);
	if (ret != 0)
		return (ret);

	/*
	 * A simple search only makes sense if the key format is a string or a
	 * record number, and the value format is a single string.
	 */
	if (strcmp(cursor->key_format, "r") != 0 &&
	    strcmp(cursor->key_format, "S") != 0) {
		fprintf(stderr,
		    "%s: read command only possible when the key format is "
		    "a record number or string\n",
		    progname);
		return (1);
	}
	rkey = strcmp(cursor->key_format, "r") == 0;
	if (strcmp(cursor->value_format, "S") != 0) {
		fprintf(stderr,
		    "%s: read command only possible when the value format is "
		    "a string\n",
		    progname);
		return (1);
	}

	/*
	 * Run through the keys, returning non-zero on error or if any requested
	 * key isn't found.
	 */
	for (rval = false; *++argv != NULL;) {
		if (rkey) {
			if (util_str2recno(session, *argv, &recno))
				return (1);
			cursor->set_key(cursor, recno);
		} else
			cursor->set_key(cursor, *argv);

		switch (ret = cursor->search(cursor)) {
		case 0:
			if ((ret = cursor->get_value(cursor, &value)) != 0)
				return (util_cerr(cursor, "get_value", ret));
			if (printf("%s\n", value) < 0)
				return (util_err(session, EIO, NULL));
			break;
		case WT_NOTFOUND:
			(void)util_err(session, 0, "%s: not found", *argv);
			rval = true;
			break;
		default:
			return (util_cerr(cursor, "search", ret));
		}
	}

	return (rval ? 1 : 0);
}
コード例 #27
0
ファイル: cursor_order.c プロジェクト: AlexOreshkevich/mongo
int
main(int argc, char *argv[])
{
	SHARED_CONFIG _cfg, *cfg;
	int ch, cnt, runs;
	char *config_open, *working_dir;

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;

	cfg = &_cfg;
	config_open = NULL;
	working_dir = NULL;
	runs = 1;

	/*
	 * Explicitly initialize the shared configuration object before
	 * parsing command line options.
	 */
	cfg->append_inserters = 1;
	cfg->conn = NULL;
	cfg->ftype = ROW;
	cfg->max_nops = 1000000;
	cfg->multiple_files = false;
	cfg->nkeys = 1000;
	cfg->reverse_scanners = 5;
	cfg->reverse_scan_ops = 10;
	cfg->thread_finish = false;
	cfg->vary_nops = false;

	while ((ch = __wt_getopt(
	    progname, argc, argv, "C:Fk:h:l:n:R:r:t:vw:W:")) != EOF)
		switch (ch) {
		case 'C':			/* wiredtiger_open config */
			config_open = __wt_optarg;
			break;
		case 'F':			/* multiple files */
			cfg->multiple_files = true;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		case 'k':			/* rows */
			cfg->nkeys = (uint64_t)atol(__wt_optarg);
			break;
		case 'l':			/* log */
			if ((logfp = fopen(__wt_optarg, "w")) == NULL) {
				fprintf(stderr,
				    "%s: %s\n", __wt_optarg, strerror(errno));
				return (EXIT_FAILURE);
			}
			break;
		case 'n':			/* operations */
			cfg->max_nops = (uint64_t)atol(__wt_optarg);
			break;
		case 'R':
			cfg->reverse_scanners = (uint64_t)atol(__wt_optarg);
			break;
		case 'r':			/* runs */
			runs = atoi(__wt_optarg);
			break;
		case 't':
			switch (__wt_optarg[0]) {
			case 'f':
				cfg->ftype = FIX;
				break;
			case 'r':
				cfg->ftype = ROW;
				break;
			case 'v':
				cfg->ftype = VAR;
				break;
			default:
				return (usage());
			}
			break;
		case 'v':			/* vary operation count */
			cfg->vary_nops = true;
			break;
		case 'w':
			cfg->reverse_scan_ops = (uint64_t)atol(__wt_optarg);
			break;
		case 'W':
			cfg->append_inserters = (uint64_t)atol(__wt_optarg);
			break;
		default:
			return (usage());
		}

	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		return (usage());

	testutil_work_dir_from_path(home, 512, working_dir);

	if (cfg->vary_nops && !cfg->multiple_files) {
		fprintf(stderr,
		    "Variable op counts only supported with multiple tables\n");
		return (usage());
	}

	/* Clean up on signal. */
	(void)signal(SIGINT, onint);

	printf("%s: process %" PRIu64 "\n", progname, (uint64_t)getpid());
	for (cnt = 1; runs == 0 || cnt <= runs; ++cnt) {
		printf(
		    "    %d: %" PRIu64
		    " reverse scanners, %" PRIu64 " writers\n",
		    cnt, cfg->reverse_scanners, cfg->append_inserters);

		shutdown();			/* Clean up previous runs */

		wt_connect(cfg, config_open);	/* WiredTiger connection */

		if (ops_start(cfg))
			return (EXIT_FAILURE);

		wt_shutdown(cfg);		/* WiredTiger shut down */
	}
	return (0);
}
コード例 #28
0
ファイル: util_main.c プロジェクト: mongodb/mongo
int
main(int argc, char *argv[])
{
	WT_CONNECTION *conn;
	WT_DECL_RET;
	WT_SESSION *session;
	size_t len;
	int ch, major_v, minor_v, tret, (*func)(WT_SESSION *, int, char *[]);
	const char *cmd_config, *config, *p1, *p2, *p3, *rec_config;
	char *p, *secretkey;
	bool logoff, recover, salvage;

	conn = NULL;
	p = NULL;

	/* Get the program name. */
	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		++progname;
	command = "";

	/* Check the version against the library build. */
	(void)wiredtiger_version(&major_v, & minor_v, NULL);
	if (major_v != WIREDTIGER_VERSION_MAJOR ||
	    minor_v != WIREDTIGER_VERSION_MINOR) {
		fprintf(stderr,
		    "%s: program build version %d.%d does not match "
		    "library build version %d.%d\n",
		    progname,
		    WIREDTIGER_VERSION_MAJOR, WIREDTIGER_VERSION_MINOR,
		    major_v,  minor_v);
		return (EXIT_FAILURE);
	}

	cmd_config = config = secretkey = NULL;
	/*
	 * We default to returning an error if recovery needs to be run.
	 * Generally we expect this to be run after a clean shutdown.
	 * The printlog command disables logging entirely.  If recovery is
	 * needed, the user can specify -R to run recovery.
	 */
	rec_config = REC_ERROR;
	logoff = recover = salvage = false;
	/* Check for standard options. */
	while ((ch = __wt_getopt(progname, argc, argv, "C:E:h:LRSVv")) != EOF)
		switch (ch) {
		case 'C':			/* wiredtiger_open config */
			cmd_config = __wt_optarg;
			break;
		case 'E':			/* secret key */
			free(secretkey);	/* lint: set more than once */
			if ((secretkey = strdup(__wt_optarg)) == NULL) {
				(void)util_err(NULL, errno, NULL);
				goto err;
			}
			memset(__wt_optarg, 0, strlen(__wt_optarg));
			break;
		case 'h':			/* home directory */
			home = __wt_optarg;
			break;
		case 'L':			/* no logging */
			rec_config = REC_LOGOFF;
			logoff = true;
			break;
		case 'R':			/* recovery */
			rec_config = REC_RECOVER;
			recover = true;
			break;
		case 'S':			/* salvage */
			rec_config = REC_SALVAGE;
			salvage = true;
			break;
		case 'V':			/* version */
			printf("%s\n", wiredtiger_version(NULL, NULL, NULL));
			goto done;
		case 'v':			/* verbose */
			verbose = true;
			break;
		case '?':
		default:
			usage();
			goto err;
		}
	if ((logoff && recover) || (logoff && salvage) ||
	    (recover && salvage)) {
		fprintf(stderr, "Only one of -L, -R, and -S is allowed.\n");
		goto err;
	}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The next argument is the command name. */
	if (argc < 1) {
		usage();
		goto err;
	}
	command = argv[0];

	/* Reset getopt. */
	__wt_optreset = __wt_optind = 1;

	func = NULL;
	switch (command[0]) {
	case 'a':
		if (strcmp(command, "alter") == 0)
			func = util_alter;
		break;
	case 'b':
		if (strcmp(command, "backup") == 0)
			func = util_backup;
		break;
	case 'c':
		if (strcmp(command, "compact") == 0)
			func = util_compact;
		else if (strcmp(command, "copyright") == 0) {
			util_copyright();
			goto done;
		} else if (strcmp(command, "create") == 0) {
			func = util_create;
			config = "create";
		}
		break;
	case 'd':
		if (strcmp(command, "downgrade") == 0)
			func = util_downgrade;
		else if (strcmp(command, "drop") == 0)
			func = util_drop;
		else if (strcmp(command, "dump") == 0)
			func = util_dump;
		break;
	case 'l':
		if (strcmp(command, "list") == 0)
			func = util_list;
		else if (strcmp(command, "load") == 0) {
			func = util_load;
			config = "create";
		} else if (strcmp(command, "loadtext") == 0) {
			func = util_loadtext;
			config = "create";
		}
		break;
	case 'p':
		if (strcmp(command, "printlog") == 0) {
			func = util_printlog;
			rec_config = REC_LOGOFF;
		}
		break;
	case 'r':
		if (strcmp(command, "read") == 0)
			func = util_read;
		else if (strcmp(command, "rebalance") == 0)
			func = util_rebalance;
		else if (strcmp(command, "rename") == 0)
			func = util_rename;
		break;
	case 's':
		if (strcmp(command, "salvage") == 0)
			func = util_salvage;
		else if (strcmp(command, "stat") == 0) {
			func = util_stat;
			config = "statistics=(all)";
		}
		break;
	case 't' :
		if (strcmp(command, "truncate") == 0)
			func = util_truncate;
		break;
	case 'u':
		if (strcmp(command, "upgrade") == 0)
			func = util_upgrade;
		break;
	case 'v':
		if (strcmp(command, "verify") == 0)
			func = util_verify;
		break;
	case 'w':
		if (strcmp(command, "write") == 0)
			func = util_write;
		break;
	default:
		break;
	}
	if (func == NULL) {
		usage();
		goto err;
	}

	/* Build the configuration string. */
	len = 10;					/* some slop */
	p1 = p2 = p3 = "";
	len += strlen("error_prefix=wt");
	if (config != NULL)
		len += strlen(config);
	if (cmd_config != NULL)
		len += strlen(cmd_config);
	if (secretkey != NULL) {
		len += strlen(secretkey) + 30;
		p1 = ",encryption=(secretkey=";
		p2 = secretkey;
		p3 = ")";
	}
	len += strlen(rec_config);
	if ((p = malloc(len)) == NULL) {
		(void)util_err(NULL, errno, NULL);
		goto err;
	}
	if ((ret = __wt_snprintf(p, len, "error_prefix=wt,%s,%s,%s%s%s%s",
	    config == NULL ? "" : config,
	    cmd_config == NULL ? "" : cmd_config,
	    rec_config, p1, p2, p3)) != 0) {
		(void)util_err(NULL, ret, NULL);
		goto err;
	}
	config = p;

	/* Open the database and a session. */
	if ((ret = wiredtiger_open(home,
	    verbose ? verbose_handler : NULL, config, &conn)) != 0) {
		(void)util_err(NULL, ret, NULL);
		goto err;
	}
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
		(void)util_err(NULL, ret, NULL);
		goto err;
	}

	/* Call the function. */
	ret = func(session, argc, argv);

	if (0) {
err:		ret = 1;
	}
done:

	/* Close the database. */
	if (conn != NULL && (tret = conn->close(conn, NULL)) != 0 && ret == 0)
		ret = tret;

	free(p);
	free(secretkey);

	return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
コード例 #29
0
ファイル: parse_opts.c プロジェクト: ChineseDr/mongo
/*
 * testutil_parse_opts --
 *    Parse command line options for a test case.
 */
int
testutil_parse_opts(int argc, char * const *argv, TEST_OPTS *opts)
{
	int ch;
	size_t len;

	opts->preserve = false;
	opts->running = true;
	opts->verbose = false;

	if ((opts->progname = strrchr(argv[0], '/')) == NULL)
		opts->progname = argv[0];
	else
		++opts->progname;

	while ((ch = __wt_getopt(opts->progname,
		argc, argv, "A:h:n:o:pR:T:t:vW:")) != EOF)
		switch (ch) {
		case 'A': /* Number of append threads */
			opts->n_append_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case 'h': /* Home directory */
			opts->home = __wt_optarg;
			break;
		case 'n': /* Number of records */
			opts->nrecords = (uint64_t)atoll(__wt_optarg);
			break;
		case 'o': /* Number of operations */
			opts->nops = (uint64_t)atoll(__wt_optarg);
			break;
		case 'p': /* Preserve directory contents */
			opts->preserve = true;
			break;
		case 'R': /* Number of reader threads */
			opts->n_read_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case 'T': /* Number of threads */
			opts->nthreads = (uint64_t)atoll(__wt_optarg);
			break;
		case 't': /* Table type */
			switch (__wt_optarg[0]) {
			case 'C':
			case 'c':
				opts->table_type = TABLE_COL;
				break;
			case 'F':
			case 'f':
				opts->table_type = TABLE_FIX;
				break;
			case 'R':
			case 'r':
				opts->table_type = TABLE_ROW;
				break;
			}
			break;
		case 'v':
			opts->verbose = true;
			break;
		case 'W': /* Number of writer threads */
			opts->n_write_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case '?':
		default:
			(void)fprintf(stderr, "usage: %s "
			    "[-A append thread count] "
			    "[-h home] "
			    "[-n record count] "
			    "[-o op count] "
			    "[-p] "
			    "[-R read thread count] "
			    "[-T thread count] "
			    "[-t c|f|r table type] "
			    "[-v] "
			    "[-W write thread count] ",
			    opts->progname);
			return (1);
		}

	/*
	 * Setup the home directory. It needs to be unique for every test
	 * or the auto make parallel tester gets upset.
	 */
	len = strlen("WT_TEST.")  + strlen(opts->progname) + 10;
	opts->home = dmalloc(len);
	snprintf(opts->home, len, "WT_TEST.%s", opts->progname);

	/* Setup the default URI string */
	len = strlen("table:") + strlen(opts->progname) + 10;
	opts->uri = dmalloc(len);
	snprintf(opts->uri, len, "table:%s", opts->progname);

	return (0);
}
コード例 #30
0
ファイル: readonly.c プロジェクト: jbreams/mongo
int
main(int argc, char *argv[])
{
	WT_CONNECTION *conn, *conn2, *conn3, *conn4;
	WT_CURSOR *cursor;
	WT_ITEM data;
	WT_SESSION *session;
	uint64_t i;
	int ch, status, op, ret;
	bool child;
	const char *working_dir;
	char cmd[512];
	uint8_t buf[MAX_VAL];

	if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL)
		progname = argv[0];
	else
		++progname;
	/*
	 * Needed unaltered for system command later.
	 */
	saved_argv0 = argv[0];

	working_dir = "WT_RD";
	child = false;
	op = OP_READ;
	while ((ch = __wt_getopt(progname, argc, argv, "Rh:W")) != EOF)
		switch (ch) {
		case 'R':
			child = true;
			op = OP_READ;
			break;
		case 'W':
			child = true;
			op = OP_WRITE;
			break;
		case 'h':
			working_dir = __wt_optarg;
			break;
		default:
			usage();
		}
	argc -= __wt_optind;
	argv += __wt_optind;
	if (argc != 0)
		usage();

	/*
	 * Set up all the directory names.
	 */
	testutil_work_dir_from_path(home, sizeof(home), working_dir);
	(void)snprintf(home_wr, sizeof(home_wr), "%s%s", home, HOME_WR_SUFFIX);
	(void)snprintf(home_rd, sizeof(home_rd), "%s%s", home, HOME_RD_SUFFIX);
	(void)snprintf(
	    home_rd2, sizeof(home_rd2), "%s%s", home, HOME_RD2_SUFFIX);
	if (!child) {
		testutil_make_work_dir(home);
		testutil_make_work_dir(home_wr);
		testutil_make_work_dir(home_rd);
		testutil_make_work_dir(home_rd2);
	} else
		/*
		 * We are a child process, we just want to call
		 * the open_dbs with the directories we have.
		 * The child function will exit.
		 */
		open_dbs(op, home, home_wr, home_rd, home_rd2);

	/*
	 * Parent creates a database and table.  Then cleanly shuts down.
	 * Then copy database to read-only directory and chmod.
	 * Also copy database to read-only directory and remove the lock
	 * file.  One read-only database will have a lock file in the
	 * file system and the other will not.
	 * Parent opens all databases with read-only configuration flag.
	 * Parent forks off child who tries to also open all databases
	 * with the read-only flag.  It should error on the writeable
	 * directory, but allow it on the read-only directories.
	 * The child then confirms it can read all the data.
	 */
	/*
	 * Run in the home directory and create the table.
	 */
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open");
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "WT_CONNECTION:open_session");
	if ((ret = session->create(session,
	    uri, "key_format=Q,value_format=u")) != 0)
		testutil_die(ret, "WT_SESSION.create: %s", uri);
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		testutil_die(ret, "WT_SESSION.open_cursor: %s", uri);

	/*
	 * Write data into the table and then cleanly shut down connection.
	 */
	memset(buf, 0, sizeof(buf));
	data.data = buf;
	data.size = MAX_VAL;
	for (i = 0; i < MAX_KV; ++i) {
		cursor->set_key(cursor, i);
		cursor->set_value(cursor, &data);
		if ((ret = cursor->insert(cursor)) != 0)
			testutil_die(ret, "WT_CURSOR.insert");
	}
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");

	/*
	 * Copy the database.  Remove any lock file from one copy
	 * and chmod the copies to be read-only permissions.
	 */
	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; rm -f %s/WiredTiger.lock",
	    home, home_wr, home_wr);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; chmod 0555 %s; chmod -R 0444 %s/*",
	    home, home_rd, home_rd, home_rd);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	(void)snprintf(cmd, sizeof(cmd),
	    "cp -rp %s/* %s; rm -f %s/WiredTiger.lock; "
	    "chmod 0555 %s; chmod -R 0444 %s/*",
	    home, home_rd2, home_rd2, home_rd2, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);

	/*
	 * Run four scenarios.  Sometimes expect errors, sometimes success.
	 * The writable database directories should always fail to allow the
	 * child to open due to the lock file.  The read-only ones will only
	 * succeed when the child attempts read-only.
	 *
	 * 1.  Parent has read-only handle to all databases.  Child opens
	 *     read-only also.
	 * 2.  Parent has read-only handle to all databases.  Child opens
	 *     read-write.
	 * 3.  Parent has read-write handle to writable databases and
	 *     read-only to read-only databases.  Child opens read-only.
	 * 4.  Parent has read-write handle to writable databases and
	 *     read-only to read-only databases.  Child opens read-write.
	 */
	/*
	 * Open a connection handle to all databases.
	 */
	fprintf(stderr, " *** Expect several error messages from WT ***\n");
	/*
	 * Scenario 1.
	 */
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG_RD, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open original home");
	if ((ret = wiredtiger_open(home_wr, NULL, ENV_CONFIG_RD, &conn2)) != 0)
		testutil_die(ret, "wiredtiger_open write nolock");
	if ((ret = wiredtiger_open(home_rd, NULL, ENV_CONFIG_RD, &conn3)) != 0)
		testutil_die(ret, "wiredtiger_open readonly");
	if ((ret = wiredtiger_open(home_rd2, NULL, ENV_CONFIG_RD, &conn4)) != 0)
		testutil_die(ret, "wiredtiger_open readonly nolock");

	/*
	 * Create a child to also open a connection handle to the databases.
	 * We cannot use fork here because using fork the child inherits the
	 * same memory image.  Therefore the WT process structure is set in
	 * the child even though it should not be.  So use 'system' to spawn
	 * an entirely new process.
	 *
	 * The child will exit with success if its test passes.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -R", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Scenario 2.  Run child with writable config.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -W", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Reopen the two writable directories and rerun the child.
	 */
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn2->close(conn2, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = wiredtiger_open(home, NULL, ENV_CONFIG_RD, &conn)) != 0)
		testutil_die(ret, "wiredtiger_open original home");
	if ((ret = wiredtiger_open(home_wr, NULL, ENV_CONFIG_RD, &conn2)) != 0)
		testutil_die(ret, "wiredtiger_open write nolock");
	/*
	 * Scenario 3.  Child read-only.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -R", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Scenario 4.  Run child with writable config.
	 */
	(void)snprintf(
	    cmd, sizeof(cmd), "%s -h %s -W", saved_argv0, working_dir);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	if (WEXITSTATUS(status) != 0)
		testutil_die(WEXITSTATUS(status), "system: %s", cmd);

	/*
	 * Clean-up.
	 */
	if ((ret = conn->close(conn, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn2->close(conn2, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn3->close(conn3, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	if ((ret = conn4->close(conn4, NULL)) != 0)
		testutil_die(ret, "WT_CONNECTION:close");
	/*
	 * We need to chmod the read-only databases back so that they can
	 * be removed by scripts.
	 */
	(void)snprintf(cmd, sizeof(cmd), "chmod 0777 %s %s", home_rd, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	(void)snprintf(cmd, sizeof(cmd), "chmod -R 0666 %s/* %s/*",
	    home_rd, home_rd2);
	if ((status = system(cmd)) < 0)
		testutil_die(status, "system: %s", cmd);
	printf(" *** Readonly test successful ***\n");
	return (EXIT_SUCCESS);
}