summaryrefslogtreecommitdiff
path: root/src/conn/conn_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conn/conn_log.c')
-rw-r--r--src/conn/conn_log.c91
1 files changed, 63 insertions, 28 deletions
diff --git a/src/conn/conn_log.c b/src/conn/conn_log.c
index 60f46288072..757d69bf240 100644
--- a/src/conn/conn_log.c
+++ b/src/conn/conn_log.c
@@ -133,10 +133,17 @@ __logmgr_config(
FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR);
WT_RET(__wt_config_gets(session, cfg, "log.zero_fill", &cval));
- if (cval.val != 0)
+ if (cval.val != 0) {
+ if (F_ISSET(conn, WT_CONN_READONLY))
+ WT_RET_MSG(session, EINVAL,
+ "Read-only configuration incompatible with "
+ "zero-filling log files");
FLD_SET(conn->log_flags, WT_CONN_LOG_ZERO_FILL);
+ }
WT_RET(__logmgr_sync_cfg(session, cfg));
+ if (conn->log_cond != NULL)
+ WT_RET(__wt_cond_auto_signal(session, conn->log_cond));
return (0);
}
@@ -463,7 +470,7 @@ __log_file_server(void *arg)
locked = false;
__wt_spin_unlock(session, &log->log_sync_lock);
} else {
- WT_ERR(__wt_cond_signal(
+ WT_ERR(__wt_cond_auto_signal(
session, conn->log_wrlsn_cond));
/*
* We do not want to wait potentially a second
@@ -633,7 +640,7 @@ restart:
if (slot->slot_start_lsn.l.offset !=
slot->slot_last_offset)
slot->slot_start_lsn.l.offset =
- slot->slot_last_offset;
+ (uint32_t)slot->slot_last_offset;
log->write_start_lsn = slot->slot_start_lsn;
log->write_lsn = slot->slot_end_lsn;
WT_ERR(__wt_cond_signal(
@@ -662,31 +669,54 @@ __log_wrlsn_server(void *arg)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ WT_LOG *log;
+ WT_LSN prev;
WT_SESSION_IMPL *session;
int yield;
+ bool did_work;
session = arg;
conn = S2C(session);
+ log = conn->log;
yield = 0;
+ WT_INIT_LSN(&prev);
+ did_work = false;
while (F_ISSET(conn, WT_CONN_LOG_SERVER_RUN)) {
/*
- * Write out any log record buffers.
+ * Write out any log record buffers if anything was done
+ * since last time. Only call the function to walk the
+ * slots if the system is not idle. On an idle system
+ * the alloc_lsn will not advance and the written lsn will
+ * match the alloc_lsn.
*/
- WT_ERR(__wt_log_wrlsn(session, &yield));
+ if (__wt_log_cmp(&prev, &log->alloc_lsn) != 0 ||
+ __wt_log_cmp(&log->write_lsn, &log->alloc_lsn) != 0)
+ WT_ERR(__wt_log_wrlsn(session, &yield));
+ else
+ WT_STAT_FAST_CONN_INCR(session, log_write_lsn_skip);
+ prev = log->alloc_lsn;
+ if (yield == 0)
+ did_work = true;
+ else
+ did_work = false;
/*
* If __wt_log_wrlsn did work we want to yield instead of sleep.
*/
if (yield++ < WT_THOUSAND)
__wt_yield();
else
- WT_ERR(__wt_cond_wait(
- session, conn->log_wrlsn_cond, 10000));
+ /*
+ * Send in false because if we did any work we would
+ * not be on this path.
+ */
+ WT_ERR(__wt_cond_auto_wait(
+ session, conn->log_wrlsn_cond, did_work));
}
/*
* On close we need to do this one more time because there could
* be straggling log writes that need to be written.
*/
- WT_ERR(__wt_log_force_write(session, 1));
+ WT_ERR(__wt_log_force_write(session, 1, NULL));
WT_ERR(__wt_log_wrlsn(session, NULL));
if (0) {
err: __wt_err(session, ret, "log wrlsn server error");
@@ -701,12 +731,13 @@ err: __wt_err(session, ret, "log wrlsn server error");
static WT_THREAD_RET
__log_server(void *arg)
{
+ struct timespec start, now;
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
WT_LOG *log;
WT_SESSION_IMPL *session;
- int freq_per_sec;
- bool locked, signalled;
+ uint64_t timediff;
+ bool did_work, locked, signalled;
session = arg;
conn = S2C(session);
@@ -714,11 +745,10 @@ __log_server(void *arg)
locked = signalled = false;
/*
- * Set this to the number of times per second we want to force out the
- * log slot buffer.
+ * Set this to the number of milliseconds we want to run archive and
+ * pre-allocation. Start it so that we run on the first time through.
*/
-#define WT_FORCE_PER_SECOND 20
- freq_per_sec = WT_FORCE_PER_SECOND;
+ timediff = WT_THOUSAND;
/*
* The log server thread does a variety of work. It forces out any
@@ -731,6 +761,7 @@ __log_server(void *arg)
* don't want log records sitting in the buffer over the time it
* takes to sync out an earlier file.
*/
+ did_work = true;
while (F_ISSET(conn, WT_CONN_LOG_SERVER_RUN)) {
/*
* Slots depend on future activity. Force out buffered
@@ -739,15 +770,14 @@ __log_server(void *arg)
* and a buffer may need to wait for the write_lsn to advance
* in the case of a synchronous buffer. We end up with a hang.
*/
- WT_ERR_BUSY_OK(__wt_log_force_write(session, 0));
+ WT_ERR_BUSY_OK(__wt_log_force_write(session, 0, &did_work));
/*
* We don't want to archive or pre-allocate files as often as
* we want to force out log buffers. Only do it once per second
* or if the condition was signalled.
*/
- if (--freq_per_sec <= 0 || signalled) {
- freq_per_sec = WT_FORCE_PER_SECOND;
+ if (timediff >= WT_THOUSAND || signalled) {
/*
* Perform log pre-allocation.
@@ -788,8 +818,12 @@ __log_server(void *arg)
}
/* Wait until the next event. */
- WT_ERR(__wt_cond_wait_signal(session, conn->log_cond,
- WT_MILLION / WT_FORCE_PER_SECOND, &signalled));
+
+ WT_ERR(__wt_epoch(session, &start));
+ WT_ERR(__wt_cond_auto_wait_signal(session, conn->log_cond,
+ did_work, &signalled));
+ WT_ERR(__wt_epoch(session, &now));
+ timediff = WT_TIMEDIFF_MS(now, start);
}
if (0) {
@@ -901,8 +935,9 @@ __wt_logmgr_open(WT_SESSION_IMPL *session)
*/
WT_RET(__wt_open_internal_session(conn, "log-wrlsn-server",
false, session_flags, &conn->log_wrlsn_session));
- WT_RET(__wt_cond_alloc(conn->log_wrlsn_session,
- "log write lsn server", false, &conn->log_wrlsn_cond));
+ WT_RET(__wt_cond_auto_alloc(conn->log_wrlsn_session,
+ "log write lsn server", false, 10000, WT_MILLION,
+ &conn->log_wrlsn_cond));
WT_RET(__wt_thread_create(conn->log_wrlsn_session,
&conn->log_wrlsn_tid, __log_wrlsn_server, conn->log_wrlsn_session));
conn->log_wrlsn_tid_set = true;
@@ -916,13 +951,13 @@ __wt_logmgr_open(WT_SESSION_IMPL *session)
if (conn->log_session != NULL) {
WT_ASSERT(session, conn->log_cond != NULL);
WT_ASSERT(session, conn->log_tid_set == true);
- WT_RET(__wt_cond_signal(session, conn->log_cond));
+ WT_RET(__wt_cond_auto_signal(session, conn->log_cond));
} else {
/* The log server gets its own session. */
WT_RET(__wt_open_internal_session(conn,
"log-server", false, session_flags, &conn->log_session));
- WT_RET(__wt_cond_alloc(conn->log_session,
- "log server", false, &conn->log_cond));
+ WT_RET(__wt_cond_auto_alloc(conn->log_session,
+ "log server", false, 50000, WT_MILLION, &conn->log_cond));
/*
* Start the thread.
@@ -958,7 +993,7 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session)
return (0);
}
if (conn->log_tid_set) {
- WT_TRET(__wt_cond_signal(session, conn->log_cond));
+ WT_TRET(__wt_cond_auto_signal(session, conn->log_cond));
WT_TRET(__wt_thread_join(session, conn->log_tid));
conn->log_tid_set = false;
}
@@ -973,7 +1008,7 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session)
conn->log_file_session = NULL;
}
if (conn->log_wrlsn_tid_set) {
- WT_TRET(__wt_cond_signal(session, conn->log_wrlsn_cond));
+ WT_TRET(__wt_cond_auto_signal(session, conn->log_wrlsn_cond));
WT_TRET(__wt_thread_join(session, conn->log_wrlsn_tid));
conn->log_wrlsn_tid_set = false;
}
@@ -994,9 +1029,9 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session)
}
/* Destroy the condition variables now that all threads are stopped */
- WT_TRET(__wt_cond_destroy(session, &conn->log_cond));
+ WT_TRET(__wt_cond_auto_destroy(session, &conn->log_cond));
WT_TRET(__wt_cond_destroy(session, &conn->log_file_cond));
- WT_TRET(__wt_cond_destroy(session, &conn->log_wrlsn_cond));
+ WT_TRET(__wt_cond_auto_destroy(session, &conn->log_wrlsn_cond));
WT_TRET(__wt_cond_destroy(session, &conn->log->log_sync_cond));
WT_TRET(__wt_cond_destroy(session, &conn->log->log_write_cond));