diff options
Diffstat (limited to 'src/txn')
| -rw-r--r-- | src/txn/txn.c | 17 | ||||
| -rw-r--r-- | src/txn/txn_ckpt.c | 20 | ||||
| -rw-r--r-- | src/txn/txn_log.c | 20 | ||||
| -rw-r--r-- | src/txn/txn_recover.c | 2 |
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); } |
