summaryrefslogtreecommitdiff
path: root/src/txn
diff options
context:
space:
mode:
Diffstat (limited to 'src/txn')
-rw-r--r--src/txn/txn.c17
-rw-r--r--src/txn/txn_ckpt.c20
-rw-r--r--src/txn/txn_log.c20
-rw-r--r--src/txn/txn_recover.c2
4 files changed, 42 insertions, 17 deletions
diff --git a/src/txn/txn.c b/src/txn/txn.c
index a2ae97fbd20..dd4384d9a9a 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -257,7 +257,7 @@ __txn_oldest_scan(WT_SESSION_IMPL *session,
* Sweep the running transactions to update the oldest ID required.
*/
int
-__wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
+__wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
@@ -265,9 +265,12 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
WT_TXN_GLOBAL *txn_global;
uint64_t current_id, last_running, oldest_id;
uint64_t prev_last_running, prev_oldest_id;
+ bool strict, wait;
conn = S2C(session);
txn_global = &conn->txn_global;
+ strict = LF_ISSET(WT_TXN_OLDEST_STRICT);
+ wait = LF_ISSET(WT_TXN_OLDEST_WAIT);
current_id = last_running = txn_global->current;
prev_last_running = txn_global->last_running;
@@ -278,11 +281,11 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
* oldest ID isn't too far behind, avoid scanning.
*/
if (prev_oldest_id == current_id ||
- (!force && WT_TXNID_LT(current_id, prev_oldest_id + 100)))
+ (!strict && WT_TXNID_LT(current_id, prev_oldest_id + 100)))
return (0);
/* First do a read-only scan. */
- if (force)
+ if (wait)
WT_RET(__wt_readlock(session, txn_global->scan_rwlock));
else if ((ret =
__wt_try_readlock(session, txn_global->scan_rwlock)) != 0)
@@ -295,13 +298,13 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
* non-forced updates), give up.
*/
if ((oldest_id == prev_oldest_id ||
- (!force && WT_TXNID_LT(oldest_id, prev_oldest_id + 100))) &&
+ (!strict && WT_TXNID_LT(oldest_id, prev_oldest_id + 100))) &&
((last_running == prev_last_running) ||
- (!force && WT_TXNID_LT(last_running, prev_last_running + 100))))
+ (!strict && WT_TXNID_LT(last_running, prev_last_running + 100))))
return (0);
/* It looks like an update is necessary, wait for exclusive access. */
- if (force)
+ if (wait)
WT_RET(__wt_writelock(session, txn_global->scan_rwlock));
else if ((ret =
__wt_try_writelock(session, txn_global->scan_rwlock)) != 0)
@@ -343,6 +346,7 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
if (WT_TXNID_LT(txn_global->last_running, last_running)) {
txn_global->last_running = last_running;
+#ifdef HAVE_VERBOSE
/* Output a verbose message about long-running transactions,
* but only when some progress is being made. */
if (WT_VERBOSE_ISSET(session, WT_VERB_TRANSACTION) &&
@@ -355,6 +359,7 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, bool force)
oldest_session->lastop,
oldest_session->txn.snap_min));
}
+#endif
}
done: WT_TRET(__wt_writeunlock(session, txn_global->scan_rwlock));
diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c
index c1b435d9897..51d26b9aed6 100644
--- a/src/txn/txn_ckpt.c
+++ b/src/txn/txn_ckpt.c
@@ -350,6 +350,7 @@ __checkpoint_verbose_track(WT_SESSION_IMPL *session,
static int
__txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
{
+ struct timespec fsync_start, fsync_stop;
struct timespec start, stop, verb_timer;
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
@@ -359,6 +360,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
WT_TXN_STATE *txn_state;
void *saved_meta_next;
u_int i;
+ uint64_t fsync_duration_usecs;
bool full, idle, logging, tracking;
const char *txn_cfg[] = { WT_CONFIG_BASE(session,
WT_SESSION_begin_transaction), "isolation=snapshot", NULL };
@@ -404,7 +406,8 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
* This is particularly important for compact, so that all dirty pages
* can be fully written.
*/
- WT_ERR(__wt_txn_update_oldest(session, true));
+ WT_ERR(__wt_txn_update_oldest(
+ session, WT_TXN_OLDEST_STRICT | WT_TXN_OLDEST_WAIT));
/* Flush data-sources before we start the checkpoint. */
WT_ERR(__checkpoint_data_source(session, cfg));
@@ -424,7 +427,13 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
* completion. Do it after flushing the pages to give the
* asynchronous flush as much time as possible before we wait.
*/
+ WT_ERR(__wt_epoch(session, &fsync_start));
WT_ERR(__checkpoint_apply(session, cfg, __wt_checkpoint_sync));
+ WT_ERR(__wt_epoch(session, &fsync_stop));
+ fsync_duration_usecs = WT_TIMEDIFF_US(fsync_stop, fsync_start);
+ WT_STAT_FAST_CONN_INCR(session, txn_checkpoint_fsync_pre);
+ WT_STAT_FAST_CONN_INCRV(session,
+ txn_checkpoint_fsync_pre_duration, fsync_duration_usecs);
/* Tell logging that we are about to start a database checkpoint. */
if (full && logging)
@@ -523,7 +532,13 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
* Checkpoints have to hit disk (it would be reasonable to configure for
* lazy checkpoints, but we don't support them yet).
*/
+ WT_ERR(__wt_epoch(session, &fsync_start));
WT_ERR(__checkpoint_apply(session, cfg, __wt_checkpoint_sync));
+ WT_ERR(__wt_epoch(session, &fsync_stop));
+ fsync_duration_usecs = WT_TIMEDIFF_US(fsync_stop, fsync_start);
+ WT_STAT_FAST_CONN_INCR(session, txn_checkpoint_fsync_post);
+ WT_STAT_FAST_CONN_INCRV(session,
+ txn_checkpoint_fsync_post_duration, fsync_duration_usecs);
WT_ERR(__checkpoint_verbose_track(session,
"sync completed", &verb_timer));
@@ -1284,7 +1299,8 @@ __wt_checkpoint_close(WT_SESSION_IMPL *session, bool final)
* for active readers.
*/
if (!btree->modified && !bulk) {
- WT_RET(__wt_txn_update_oldest(session, true));
+ WT_RET(__wt_txn_update_oldest(
+ session, WT_TXN_OLDEST_STRICT | WT_TXN_OLDEST_WAIT));
return (__wt_txn_visible_all(session, btree->rec_max_txn) ?
__wt_cache_op(session, WT_SYNC_DISCARD) : EBUSY);
}
diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c
index da2670fb344..470515244f3 100644
--- a/src/txn/txn_log.c
+++ b/src/txn/txn_log.c
@@ -156,6 +156,7 @@ err: __wt_logrec_free(session, &logrec);
int
__wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
{
+ WT_DECL_RET;
WT_ITEM *logrec;
WT_TXN *txn;
WT_TXN_OP *op;
@@ -179,24 +180,25 @@ __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
switch (op->type) {
case WT_TXN_OP_BASIC:
- return (__txn_op_log(session, logrec, op, cbt));
+ ret = __txn_op_log(session, logrec, op, cbt);
+ break;
case WT_TXN_OP_INMEM:
case WT_TXN_OP_REF:
/* Nothing to log, we're done. */
- return (0);
+ break;
case WT_TXN_OP_TRUNCATE_COL:
- return (__wt_logop_col_truncate_pack(session, logrec,
+ ret = __wt_logop_col_truncate_pack(session, logrec,
op->fileid,
- op->u.truncate_col.start, op->u.truncate_col.stop));
+ op->u.truncate_col.start, op->u.truncate_col.stop);
+ break;
case WT_TXN_OP_TRUNCATE_ROW:
- return (__wt_logop_row_truncate_pack(session, txn->logrec,
+ ret = __wt_logop_row_truncate_pack(session, txn->logrec,
op->fileid,
&op->u.truncate_row.start, &op->u.truncate_row.stop,
- (uint32_t)op->u.truncate_row.mode));
- WT_ILLEGAL_VALUE(session);
+ (uint32_t)op->u.truncate_row.mode);
+ break;
}
-
- /* NOTREACHED */
+ return (ret);
}
/*
diff --git a/src/txn/txn_recover.c b/src/txn/txn_recover.c
index 1ea4dba1152..bd004e0f837 100644
--- a/src/txn/txn_recover.c
+++ b/src/txn/txn_recover.c
@@ -424,6 +424,7 @@ __wt_txn_recover(WT_SESSION_IMPL *session)
false, WT_SESSION_NO_LOGGING, &session));
r.session = session;
+ F_SET(conn, WT_CONN_RECOVERING);
WT_ERR(__wt_metadata_search(session, WT_METAFILE_URI, &config));
WT_ERR(__recovery_setup_file(&r, WT_METAFILE_URI, config));
WT_ERR(__wt_metadata_cursor_open(session, NULL, &metac));
@@ -566,6 +567,7 @@ err: WT_TRET(__recovery_free(&r));
WT_TRET(__wt_evict_destroy(session));
WT_TRET(session->iface.close(&session->iface, NULL));
+ F_CLR(conn, WT_CONN_RECOVERING);
return (ret);
}