/* * __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); }
/* * __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); }