diff options
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | src/meta/meta_track.c | 29 | ||||
-rw-r--r-- | src/session/session_dhandle.c | 10 |
3 files changed, 39 insertions, 1 deletions
diff --git a/src/include/extern.h b/src/include/extern.h index a259294caff..082ffb07a45 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -426,6 +426,7 @@ extern int __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key); extern int __wt_metadata_search( WT_SESSION_IMPL *session, const char *key, char **valuep); extern void __wt_meta_track_discard(WT_SESSION_IMPL *session); extern int __wt_meta_track_on(WT_SESSION_IMPL *session); +extern int __wt_meta_track_find_handle( WT_SESSION_IMPL *session, const char *name, const char *checkpoint); extern int __wt_meta_track_off(WT_SESSION_IMPL *session, int need_sync, int unroll); extern int __wt_meta_track_sub_on(WT_SESSION_IMPL *session); extern int __wt_meta_track_sub_off(WT_SESSION_IMPL *session); diff --git a/src/meta/meta_track.c b/src/meta/meta_track.c index 3bc6a1f9d60..62d4df47ff6 100644 --- a/src/meta/meta_track.c +++ b/src/meta/meta_track.c @@ -184,6 +184,35 @@ free: trk->op = WT_ST_EMPTY; } /* + * __wt_meta_track_find_handle -- + * Check if we have already seen a handle. + */ +int +__wt_meta_track_find_handle( + WT_SESSION_IMPL *session, const char *name, const char *checkpoint) +{ + WT_META_TRACK *trk, *trk_orig; + + WT_ASSERT(session, + WT_META_TRACKING(session) && session->meta_track_nest > 0); + + trk_orig = session->meta_track; + trk = session->meta_track_next; + + while (--trk >= trk_orig) { + if (trk->op != WT_ST_LOCK) + continue; + if (strcmp(trk->dhandle->name, name) == 0 && + ((trk->dhandle->checkpoint == NULL && checkpoint == NULL) || + (trk->dhandle->checkpoint != NULL && + strcmp(trk->dhandle->checkpoint, checkpoint) == 0))) + return (0); + } + + return (WT_NOTFOUND); +} + +/* * __wt_meta_track_off -- * Turn off metadata operation tracking, unrolling on error. */ diff --git a/src/session/session_dhandle.c b/src/session/session_dhandle.c index 0825f783ca3..a6c9fb867e7 100644 --- a/src/session/session_dhandle.c +++ b/src/session/session_dhandle.c @@ -438,9 +438,18 @@ __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint) WT_DATA_HANDLE *dhandle, *saved_dhandle; WT_DECL_RET; + WT_ASSERT(session, WT_META_TRACKING(session)); saved_dhandle = session->dhandle; /* + * If we already have the checkpoint locked, don't attempt to lock + * it again. + */ + if ((ret = __wt_meta_track_find_handle( + session, saved_dhandle->name, checkpoint)) != WT_NOTFOUND) + return (ret); + + /* * Get the checkpoint handle exclusive, so no one else can access it * while we are creating the new checkpoint. */ @@ -463,7 +472,6 @@ __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint) dhandle = session->dhandle; F_SET(dhandle, WT_DHANDLE_DISCARD); - WT_ASSERT(session, WT_META_TRACKING(session)); WT_ERR(__wt_meta_track_handle_lock(session, 0)); /* Restore the original btree in the session. */ |