diff options
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | src/meta/meta_track.c | 34 | ||||
-rw-r--r-- | src/session/session_snapshot.c | 13 |
3 files changed, 42 insertions, 6 deletions
diff --git a/src/include/extern.h b/src/include/extern.h index d756203f2ea..8997b05bdfd 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -660,6 +660,7 @@ extern int __wt_meta_track_on(WT_SESSION_IMPL *session); extern int __wt_meta_track_off(WT_SESSION_IMPL *session, int unroll); extern int __wt_meta_track_sub_on(WT_SESSION_IMPL *session); extern int __wt_meta_track_sub_off(WT_SESSION_IMPL *session); +extern int __wt_meta_track_checkpoint(WT_SESSION_IMPL *session); extern int __wt_meta_track_insert(WT_SESSION_IMPL *session, const char *key); extern int __wt_meta_track_update(WT_SESSION_IMPL *session, const char *key); extern int __wt_meta_track_fileop( WT_SESSION_IMPL *session, diff --git a/src/meta/meta_track.c b/src/meta/meta_track.c index b7d5c77bc35..9f17789a1cc 100644 --- a/src/meta/meta_track.c +++ b/src/meta/meta_track.c @@ -15,6 +15,7 @@ typedef struct __wt_meta_track { enum { WT_ST_EMPTY, /* Unused slot */ + WT_ST_CHECKPOINT, /* Complete a checkpoint */ WT_ST_FILEOP, /* File operation */ WT_ST_LOCK, /* Lock a handle */ WT_ST_REMOVE, /* Remove a metadata entry */ @@ -91,13 +92,25 @@ __meta_track_apply(WT_SESSION_IMPL *session, WT_META_TRACK *trk, int unroll) WT_DECL_RET; int tret; - /* Unlock handles regardless of whether we are unrolling. */ - if (!unroll && trk->op != WT_ST_LOCK) + /* + * Unlock handles and complete checkpoints regardless of whether we are + * unrolling. + */ + if (!unroll && trk->op != WT_ST_CHECKPOINT && trk->op != WT_ST_LOCK) goto free; switch (trk->op) { case WT_ST_EMPTY: /* Unused slot */ break; + case WT_ST_CHECKPOINT: /* Checkpoint, see above */ + saved_btree = session->btree; + session->btree = trk->btree; + if (!unroll) + WT_TRET(__wt_bm_snapshot_resolve(session, NULL)); + /* Release the snapshot lock */ + __wt_rwunlock(session, session->btree->snaplock); + session->btree = saved_btree; + break; case WT_ST_LOCK: /* Handle lock, see above */ saved_btree = session->btree; session->btree = trk->btree; @@ -234,6 +247,23 @@ __wt_meta_track_sub_off(WT_SESSION_IMPL *session) } /* + * __wt_meta_track_checkpoint -- + * Track a handle involved in a checkpoint. + */ +int +__wt_meta_track_checkpoint(WT_SESSION_IMPL *session) +{ + WT_META_TRACK *trk; + + WT_ASSERT(session, session->btree != NULL); + + WT_RET(__meta_track_next(session, &trk)); + + trk->op = WT_ST_CHECKPOINT; + trk->btree = session->btree; + return (0); +} +/* * __wt_meta_track_insert -- * Track an insert operation. */ diff --git a/src/session/session_snapshot.c b/src/session/session_snapshot.c index 131c37a3a2d..643d08aa1c0 100644 --- a/src/session/session_snapshot.c +++ b/src/session/session_snapshot.c @@ -101,10 +101,10 @@ __snapshot_worker( WT_BTREE *btree; WT_DECL_RET; WT_SNAPSHOT *deleted, *snap, *snapbase; - int force, matched; + int force, matched, tracked; btree = session->btree; - matched = 0; + matched = tracked = 0; snap = snapbase = NULL; /* Snapshots are single-threaded. */ @@ -246,11 +246,16 @@ nomatch: WT_ERR_MSG(session, EINVAL, "cache flush failed to create a snapshot"); } else { WT_ERR(__wt_meta_snaplist_set(session, btree->name, snapbase)); - WT_ERR(__wt_bm_snapshot_resolve(session, snapbase)); + if (WT_META_TRACKING(session)) { + WT_ERR(__wt_meta_track_checkpoint(session)); + tracked = 1; + } else + WT_ERR(__wt_bm_snapshot_resolve(session, snapbase)); } err: __wt_meta_snaplist_free(session, snapbase); - __wt_rwunlock(session, btree->snaplock); + if (!tracked) + __wt_rwunlock(session, btree->snaplock); return (ret); } |