summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/extern.h1
-rw-r--r--src/meta/meta_track.c34
-rw-r--r--src/session/session_snapshot.c13
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);
}