Ejemplo n.º 1
0
/*
 * __compact_worker --
 *	Function to alternate between checkpoints and compaction calls.
 */
static int
__compact_worker(WT_SESSION_IMPL *session)
{
	WT_DECL_RET;
	u_int i, loop;
	bool didwork;

	/*
	 * Reset the handles' compaction skip flag (we don't bother setting
	 * or resetting it when we finish compaction, it's simpler to do it
	 * once, here).
	 */
	for (i = 0; i < session->op_handle_next; ++i)
		session->op_handle[i]->compact_skip = false;

	/*
	 * Perform an initial checkpoint (see this file's leading comment for
	 * details).
	 */
	WT_ERR(__compact_checkpoint(session));

	/*
	 * We compact 10% of a file on each pass (but the overall size of the
	 * file is decreasing each time, so we're not compacting 10% of the
	 * original file each time). Try 100 times (which is clearly more than
	 * we need); quit if we make no progress.
	 */
	for (loop = 0; loop < 100; ++loop) {
		/* Step through the list of files being compacted. */
		for (didwork = false, i = 0; i < session->op_handle_next; ++i) {
			/* Skip objects where there's no more work. */
			if (session->op_handle[i]->compact_skip)
				continue;

			session->compact_state = WT_COMPACT_RUNNING;
			WT_WITH_DHANDLE(session,
			    session->op_handle[i], ret = __wt_compact(session));
			WT_ERR(ret);

			/* If we did no work, skip this file in the future. */
			if (session->compact_state == WT_COMPACT_SUCCESS)
				didwork = true;
			else
				session->op_handle[i]->compact_skip = true;
		}
		if (!didwork)
			break;

		/*
		 * Perform two checkpoints (see this file's leading comment for
		 * details).
		 */
		WT_ERR(__compact_checkpoint(session));
		WT_ERR(__compact_checkpoint(session));
	}

err:	session->compact_state = WT_COMPACT_NONE;

	return (ret);
}
Ejemplo n.º 2
0
/*
 * __compact_worker --
 *	Function to alternate between checkpoints and compaction calls.
 */
static int
__compact_worker(WT_SESSION_IMPL *session)
{
	WT_DECL_RET;
	u_int i, loop;
	bool another_pass;

	/*
	 * Reset the handles' compaction skip flag (we don't bother setting
	 * or resetting it when we finish compaction, it's simpler to do it
	 * once, here).
	 */
	for (i = 0; i < session->op_handle_next; ++i)
		session->op_handle[i]->compact_skip = false;

	/*
	 * Perform an initial checkpoint (see this file's leading comment for
	 * details).
	 */
	WT_ERR(__compact_checkpoint(session));

	/*
	 * We compact 10% of a file on each pass (but the overall size of the
	 * file is decreasing each time, so we're not compacting 10% of the
	 * original file each time). Try 100 times (which is clearly more than
	 * we need); quit if we make no progress.
	 */
	for (loop = 0; loop < 100; ++loop) {
		/* Step through the list of files being compacted. */
		for (another_pass = false,
		    i = 0; i < session->op_handle_next; ++i) {
			/* Skip objects where there's no more work. */
			if (session->op_handle[i]->compact_skip)
				continue;

			session->compact_state = WT_COMPACT_RUNNING;
			WT_WITH_DHANDLE(session,
			    session->op_handle[i], ret = __wt_compact(session));

			/*
			 * If successful and we did work, schedule another pass.
			 * If successful and we did no work, skip this file in
			 * the future.
			 */
			if (ret == 0) {
				if (session->
				    compact_state == WT_COMPACT_SUCCESS)
					another_pass = true;
				else
					session->
					    op_handle[i]->compact_skip = true;
				continue;
			}

			/*
			 * If compaction failed because checkpoint was running,
			 * continue with the next handle. We might continue to
			 * race with checkpoint on each handle, but that's OK,
			 * we'll step through all the handles, and then we'll
			 * block until a checkpoint completes.
			 *
			 * Just quit if eviction is the problem.
			 */
			if (ret == EBUSY) {
				if (__wt_cache_stuck(session)) {
					WT_ERR_MSG(session, EBUSY,
					    "compaction halted by eviction "
					    "pressure");
				}
				ret = 0;
				another_pass = true;
			}
			WT_ERR(ret);
		}
		if (!another_pass)
			break;

		/*
		 * Perform two checkpoints (see this file's leading comment for
		 * details).
		 */
		WT_ERR(__compact_checkpoint(session));
		WT_ERR(__compact_checkpoint(session));
	}

err:	session->compact_state = WT_COMPACT_NONE;

	return (ret);
}