/* * __ckpt_server_config -- * Parse and setup the checkpoint server options. */ static int __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, int *startp) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_ITEM(tmp); WT_DECL_RET; char *p; conn = S2C(session); /* * The checkpoint configuration requires a wait time and/or a log * size -- if one is not set, we're not running at all. * Checkpoints based on log size also require logging be enabled. */ WT_RET(__wt_config_gets(session, cfg, "checkpoint.wait", &cval)); conn->ckpt_usecs = (long)cval.val * 1000000; WT_RET(__wt_config_gets(session, cfg, "checkpoint.log_size", &cval)); conn->ckpt_logsize = (wt_off_t)cval.val; __wt_log_written_reset(session); if ((conn->ckpt_usecs == 0 && conn->ckpt_logsize == 0) || (conn->ckpt_logsize && conn->ckpt_usecs == 0 && !FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED))) { *startp = 0; return (0); } *startp = 1; /* * The application can specify a checkpoint name, which we ignore if * it's our default. */ WT_RET(__wt_config_gets(session, cfg, "checkpoint.name", &cval)); if (cval.len != 0 && !WT_STRING_MATCH(WT_CHECKPOINT, cval.str, cval.len)) { WT_RET(__wt_checkpoint_name_ok(session, cval.str, cval.len)); WT_RET(__wt_scr_alloc(session, cval.len + 20, &tmp)); WT_ERR(__wt_buf_fmt( session, tmp, "name=%.*s", (int)cval.len, cval.str)); WT_ERR(__wt_strdup(session, tmp->data, &p)); __wt_free(session, conn->ckpt_config); conn->ckpt_config = p; } err: __wt_scr_free(session, &tmp); return (ret); }
/* * __ckpt_server_config -- * Parse and setup the checkpoint server options. */ static int __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; *startp = false; conn = S2C(session); WT_RET(__wt_config_gets(session, cfg, "checkpoint.wait", &cval)); conn->ckpt_usecs = (uint64_t)cval.val * WT_MILLION; WT_RET(__wt_config_gets(session, cfg, "checkpoint.log_size", &cval)); conn->ckpt_logsize = (wt_off_t)cval.val; /* * The checkpoint configuration requires a wait time and/or a log size, * if neither is set, we're not running at all. Checkpoints based on log * size also require logging be enabled. */ if (conn->ckpt_usecs != 0 || (conn->ckpt_logsize != 0 && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED))) { /* * If checkpointing based on log data, use a minimum of the * log file size. The logging subsystem has already been * initialized. */ if (conn->ckpt_logsize != 0 && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) conn->ckpt_logsize = WT_MAX( conn->ckpt_logsize, conn->log_file_max); /* Checkpoints are incompatible with in-memory configuration */ WT_RET(__wt_config_gets(session, cfg, "in_memory", &cval)); if (cval.val != 0) WT_RET_MSG(session, EINVAL, "checkpoint configuration incompatible with " "in-memory configuration"); __wt_log_written_reset(session); *startp = true; } return (0); }
/* * __ckpt_server -- * The checkpoint server thread. */ static void * __ckpt_server(void *arg) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION *wt_session; WT_SESSION_IMPL *session; session = arg; conn = S2C(session); wt_session = (WT_SESSION *)session; while (F_ISSET(conn, WT_CONN_SERVER_RUN) && F_ISSET(conn, WT_CONN_SERVER_CHECKPOINT)) { /* Checkpoint the database. */ WT_ERR(wt_session->checkpoint(wt_session, conn->ckpt_config)); /* Reset. */ if (conn->ckpt_logsize) { __wt_log_written_reset(session); conn->ckpt_signalled = 0; /* * In case we crossed the log limit during the * checkpoint and the condition variable was already * signalled, do a tiny wait to clear it so we don't do * another checkpoint immediately. */ WT_ERR(__wt_cond_wait(session, conn->ckpt_cond, 1)); } /* * Wait... * NOTE: If the user only configured logsize, then usecs * will be 0 and this wait won't return until signalled. */ WT_ERR( __wt_cond_wait(session, conn->ckpt_cond, conn->ckpt_usecs)); } if (0) { err: WT_PANIC_MSG(session, ret, "checkpoint server error"); } return (NULL); }