summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-10-25 13:36:03 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-10-25 13:36:03 +1100
commitcaa48be8d8031938297ce53604b6c9c6a0f2eff0 (patch)
tree3365549d310789fc197d88404f71fde80830887b
parent448ac2fd58f312861c55508dc0976138831d0775 (diff)
downloadmongo-caa48be8d8031938297ce53604b6c9c6a0f2eff0.tar.gz
Allow meta_tracking transactions to be nested.
Before this change, calls that performed an operation on multiple objects (such as creating a table that implicitly creates a column group) would checkpoint when the first nested child completed. This could leave the metadata incomplete if a process exited without calling `WT_CONNECTION::close`. closes #373
-rw-r--r--src/include/api.h1
-rw-r--r--src/meta/meta_track.c11
2 files changed, 9 insertions, 3 deletions
diff --git a/src/include/api.h b/src/include/api.h
index 677742c4c6e..4374cf05265 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -78,6 +78,7 @@ struct __wt_session_impl {
void *meta_track_next; /* Current position */
void *meta_track_sub; /* Child transaction / save point */
size_t meta_track_alloc; /* Currently allocated */
+ int meta_track_nest; /* Nesting level of meta transaction */
#define WT_META_TRACKING(session) (session->meta_track_next != NULL)
TAILQ_HEAD(__tables, __wt_table) tables;
diff --git a/src/meta/meta_track.c b/src/meta/meta_track.c
index 9adf19a4dbd..eec19d1990e 100644
--- a/src/meta/meta_track.c
+++ b/src/meta/meta_track.c
@@ -36,7 +36,7 @@ __meta_track_next(WT_SESSION_IMPL *session, WT_META_TRACK **trkp)
{
size_t offset, sub_off;
- if (!WT_META_TRACKING(session))
+ if (session->meta_track_next == NULL)
session->meta_track_next = session->meta_track;
offset = WT_PTRDIFF(session->meta_track_next, session->meta_track);
@@ -83,7 +83,10 @@ __wt_meta_track_discard(WT_SESSION_IMPL *session)
int
__wt_meta_track_on(WT_SESSION_IMPL *session)
{
- return (__meta_track_next(session, NULL));
+ if (session->meta_track_nest++ == 0)
+ WT_RET(__meta_track_next(session, NULL));
+
+ return (0);
}
static int
@@ -188,7 +191,9 @@ __wt_meta_track_off(WT_SESSION_IMPL *session, int unroll)
WT_META_TRACK *trk, *trk_orig;
const char *ckpt_cfg[] = API_CONF_DEFAULTS(session, checkpoint, NULL);
- if (!WT_META_TRACKING(session))
+ WT_ASSERT(session,
+ WT_META_TRACKING(session) && session->meta_track_nest > 0);
+ if (--session->meta_track_nest != 0)
return (0);
trk_orig = session->meta_track;