diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2015-07-20 17:21:40 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-08-04 14:01:45 +1000 |
commit | 36d0d62116a1da610a0790765a0fecb8d10daeb0 (patch) | |
tree | 4171be95e858a4f775c8edf3e53ec0749244b967 | |
parent | a58397f4dec5154944102751bb268f83dea7f5c2 (diff) | |
download | mongo-36d0d62116a1da610a0790765a0fecb8d10daeb0.tar.gz |
Merge pull request #2066 from wiredtiger/meta-track-postcommit
(cherry picked from commit 3e2e7e6224725c69684ba18b0ee1746f9e490cb1)
-rw-r--r-- | src/meta/meta_track.c | 100 |
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); |