summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2015-07-20 17:21:40 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2015-08-04 14:01:45 +1000
commit36d0d62116a1da610a0790765a0fecb8d10daeb0 (patch)
tree4171be95e858a4f775c8edf3e53ec0749244b967
parenta58397f4dec5154944102751bb268f83dea7f5c2 (diff)
downloadmongo-36d0d62116a1da610a0790765a0fecb8d10daeb0.tar.gz
Merge pull request #2066 from wiredtiger/meta-track-postcommit
(cherry picked from commit 3e2e7e6224725c69684ba18b0ee1746f9e490cb1)
-rw-r--r--src/meta/meta_track.c100
1 files changed, 69 insertions, 31 deletions
diff --git a/src/meta/meta_track.c b/src/meta/meta_track.c
index 66e7e3977f4..87e11634ce2 100644
--- a/src/meta/meta_track.c
+++ b/src/meta/meta_track.c
@@ -67,6 +67,18 @@ __meta_track_next(WT_SESSION_IMPL *session, WT_META_TRACK **trkp)
}
/*
+ * __meta_track_clear --
+ * Clear the structure.
+ */
+static void
+__meta_track_clear(WT_SESSION_IMPL *session, WT_META_TRACK *trk)
+{
+ __wt_free(session, trk->a);
+ __wt_free(session, trk->b);
+ memset(trk, 0, sizeof(WT_META_TRACK));
+}
+
+/*
* __wt_meta_track_discard --
* Cleanup metadata tracking when closing a session.
*/
@@ -96,31 +108,21 @@ __wt_meta_track_on(WT_SESSION_IMPL *session)
* Apply the changes in a metadata tracking record.
*/
static int
-__meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk, int unroll)
+__meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk)
{
WT_BM *bm;
WT_BTREE *btree;
WT_DECL_RET;
int tret;
- /*
- * Unlock handles and complete checkpoints regardless of whether we are
- * unrolling.
- */
- if (!unroll && trk->op != WT_ST_CHECKPOINT &&
- trk->op != WT_ST_DROP_COMMIT && trk->op != WT_ST_LOCK)
- goto free;
-
switch (trk->op) {
case WT_ST_EMPTY: /* Unused slot */
break;
case WT_ST_CHECKPOINT: /* Checkpoint, see above */
- if (!unroll) {
- btree = trk->dhandle->handle;
- bm = btree->bm;
- WT_WITH_DHANDLE(session, trk->dhandle,
- WT_TRET(bm->checkpoint_resolve(bm, session)));
- }
+ btree = trk->dhandle->handle;
+ bm = btree->bm;
+ WT_WITH_DHANDLE(session, trk->dhandle,
+ WT_TRET(bm->checkpoint_resolve(bm, session)));
break;
case WT_ST_DROP_COMMIT:
if ((tret = __wt_remove_if_exists(session, trk->a)) != 0) {
@@ -130,8 +132,40 @@ __meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk, int unroll)
WT_TRET(tret);
}
break;
+ case WT_ST_LOCK:
+ WT_WITH_DHANDLE(session, trk->dhandle,
+ WT_TRET(__wt_session_release_btree(session)));
+ break;
+ case WT_ST_FILEOP:
+ case WT_ST_REMOVE:
+ case WT_ST_SET:
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
+
+ __meta_track_clear(session, trk);
+ return (ret);
+}
+
+/*
+ * __meta_track_unroll --
+ * Undo the changes in a metadata tracking record.
+ */
+static int
+__meta_track_unroll(WT_SESSION_IMPL *session, WT_META_TRACK *trk)
+{
+ WT_DECL_RET;
+ int tret;
+
+ switch (trk->op) {
+ case WT_ST_EMPTY: /* Unused slot */
+ break;
+ case WT_ST_CHECKPOINT: /* Checkpoint, see above */
+ break;
+ case WT_ST_DROP_COMMIT:
+ break;
case WT_ST_LOCK: /* Handle lock, see above */
- if (unroll && trk->created)
+ if (trk->created)
F_SET(trk->dhandle, WT_DHANDLE_DISCARD);
WT_WITH_DHANDLE(session, trk->dhandle,
WT_TRET(__wt_session_release_btree(session)));
@@ -185,11 +219,7 @@ __meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk, int unroll)
WT_ILLEGAL_VALUE(session);
}
-free: trk->op = WT_ST_EMPTY;
- __wt_free(session, trk->a);
- __wt_free(session, trk->b);
- trk->dhandle = NULL;
-
+ __meta_track_clear(session, trk);
return (ret);
}
@@ -253,33 +283,41 @@ __wt_meta_track_off(WT_SESSION_IMPL *session, int need_sync, int unroll)
if (trk == trk_orig)
return (0);
- while (--trk >= trk_orig)
- WT_TRET(__meta_track_apply(session, trk, unroll));
+ if (unroll) {
+ while (--trk >= trk_orig)
+ WT_TRET(__meta_track_unroll(session, trk));
+ /* Unroll operations don't need to flush the metadata. */
+ return (ret);
+ }
/*
- * Unroll operations don't need to flush the metadata.
- *
- * Also, if we don't have the metadata handle (e.g, we're in the
- * process of creating the metadata), we can't sync it.
+ * If we don't have the metadata handle (e.g, we're in the process of
+ * creating the metadata), we can't sync it.
*/
- if (unroll || ret != 0 || !need_sync || session->meta_dhandle == NULL)
- return (ret);
+ if (!need_sync || session->meta_dhandle == NULL)
+ goto done;
/* If we're logging, make sure the metadata update was flushed. */
if (FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED)) {
if (!FLD_ISSET(S2C(session)->txn_logsync,
- WT_LOG_DSYNC | WT_LOG_FSYNC))
+ WT_LOG_DSYNC | WT_LOG_FSYNC)) {
WT_WITH_DHANDLE(session, session->meta_dhandle,
ret = __wt_txn_checkpoint_log(session,
0, WT_TXN_LOG_CKPT_SYNC, NULL));
+ WT_RET(ret);
+ }
} else {
WT_WITH_DHANDLE(session, session->meta_dhandle,
ret = __wt_checkpoint(session, NULL));
WT_RET(ret);
WT_WITH_DHANDLE(session, session->meta_dhandle,
ret = __wt_checkpoint_sync(session, NULL));
+ WT_RET(ret);
}
+done: /* Apply any tracked operations post-commit. */
+ for (; trk_orig < trk; trk_orig++)
+ WT_TRET(__meta_track_apply(session, trk_orig));
return (ret);
}
@@ -316,7 +354,7 @@ __wt_meta_track_sub_off(WT_SESSION_IMPL *session)
session->meta_track_next = session->meta_track_sub = NULL;
while (--trk >= trk_orig)
- WT_TRET(__meta_track_apply(session, trk, 0));
+ WT_TRET(__meta_track_apply(session, trk));
session->meta_track_next = trk_orig;
return (ret);