diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-07-26 14:57:01 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-07-26 14:57:01 +1000 |
commit | 26b0d0e7a1fbcee401e4d32e003f483383b883e2 (patch) | |
tree | e93f7a79900659aaaf2ba0b32282fd4915b96587 | |
parent | 15031c8608282e48e1bf382ab37b6ebc9cc8ef9a (diff) | |
download | mongo-26b0d0e7a1fbcee401e4d32e003f483383b883e2.tar.gz |
Checkpoint handles must be closed when they are overwritten.
closes #269
-rw-r--r-- | dist/s_define.list | 1 | ||||
-rw-r--r-- | src/include/btree.h | 15 | ||||
-rw-r--r-- | src/include/extern.h | 5 | ||||
-rw-r--r-- | src/session/session_btree.c | 15 | ||||
-rw-r--r-- | src/txn/txn_ckpt.c | 15 |
5 files changed, 29 insertions, 22 deletions
diff --git a/dist/s_define.list b/dist/s_define.list index 378a6c2dcf7..3e8fb2a71e8 100644 --- a/dist/s_define.list +++ b/dist/s_define.list @@ -6,6 +6,7 @@ API_SESSION_INIT FLD_CLR HAVE_ATOMICS LF_CLR +LF_SET LLONG_MAX LLONG_MIN SIZE_CHECK diff --git a/src/include/btree.h b/src/include/btree.h index c0405455517..9f3c1ef0b60 100644 --- a/src/include/btree.h +++ b/src/include/btree.h @@ -114,13 +114,14 @@ struct __wt_btree { WT_BTREE_STATS *stats; /* Btree statistics */ #define WT_BTREE_BULK 0x0001 /* Bulk-load handle */ -#define WT_BTREE_EXCLUSIVE 0x0002 /* Need exclusive access to handle */ -#define WT_BTREE_LOCK_ONLY 0x0004 /* Handle is only needed for locking */ -#define WT_BTREE_NO_EVICTION 0x0008 /* The file isn't evicted */ -#define WT_BTREE_OPEN 0x0010 /* Handle is open */ -#define WT_BTREE_SALVAGE 0x0020 /* Handle is for salvage */ -#define WT_BTREE_UPGRADE 0x0040 /* Handle is for upgrade */ -#define WT_BTREE_VERIFY 0x0080 /* Handle is for verify */ +#define WT_BTREE_DISCARD 0x0002 /* Discard on release */ +#define WT_BTREE_EXCLUSIVE 0x0004 /* Need exclusive access to handle */ +#define WT_BTREE_LOCK_ONLY 0x0008 /* Handle is only needed for locking */ +#define WT_BTREE_NO_EVICTION 0x0010 /* The file isn't evicted */ +#define WT_BTREE_OPEN 0x0020 /* Handle is open */ +#define WT_BTREE_SALVAGE 0x0040 /* Handle is for salvage */ +#define WT_BTREE_UPGRADE 0x0080 /* Handle is for upgrade */ +#define WT_BTREE_VERIFY 0x0100 /* Handle is for verify */ uint32_t flags; }; diff --git a/src/include/extern.h b/src/include/extern.h index 26843448406..77bc66af41c 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -929,9 +929,8 @@ extern int __wt_session_get_btree(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], uint32_t flags); -extern int __wt_session_lock_checkpoint( WT_SESSION_IMPL *session, - const char *checkpoint, - uint32_t flags); +extern int __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, + const char *checkpoint); extern int __wt_session_discard_btree( WT_SESSION_IMPL *session, WT_BTREE_SESSION *btree_session); extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]); diff --git a/src/session/session_btree.c b/src/session/session_btree.c index 06cff9a8986..d343bf992e2 100644 --- a/src/session/session_btree.c +++ b/src/session/session_btree.c @@ -108,7 +108,7 @@ __wt_session_release_btree(WT_SESSION_IMPL *session) * If we had special flags set, close the handle so that future access * can get a handle without special flags. */ - if (F_ISSET(btree, WT_BTREE_SPECIAL_FLAGS)) { + if (F_ISSET(btree, WT_BTREE_DISCARD | WT_BTREE_SPECIAL_FLAGS)) { WT_ASSERT(session, F_ISSET(btree, WT_BTREE_EXCLUSIVE)); ret = __wt_conn_btree_sync_and_close(session); @@ -225,8 +225,7 @@ __wt_session_get_btree(WT_SESSION_IMPL *session, * Lock the btree handle for the given checkpoint name. */ int -__wt_session_lock_checkpoint( - WT_SESSION_IMPL *session, const char *checkpoint, uint32_t flags) +__wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint) { WT_BTREE *btree; WT_DECL_RET; @@ -240,8 +239,14 @@ __wt_session_lock_checkpoint( WT_ERR(__wt_buf_fmt(session, buf, "checkpoint=\"%s\"", checkpoint)); cfg[0] = buf->data; - LF_SET(WT_BTREE_LOCK_ONLY); - WT_ERR(__wt_session_get_btree(session, btree->name, cfg, flags)); + WT_ERR(__wt_session_get_btree(session, btree->name, cfg, + WT_BTREE_EXCLUSIVE | WT_BTREE_LOCK_ONLY)); + + /* + * We lock checkpoint handles that we are overwriting, so the handle + * must be closed when we release it. + */ + F_SET(session->btree, WT_BTREE_DISCARD); WT_ASSERT(session, WT_META_TRACKING(session)); WT_ERR(__wt_meta_track_handle_lock(session)); diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c index 41dc5799826..b9fa7d721be 100644 --- a/src/txn/txn_ckpt.c +++ b/src/txn/txn_ckpt.c @@ -262,13 +262,14 @@ __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) name_alloc = NULL; /* - * Get the list of checkpoints for this file. If there's no reference, - * this file is dead. Discard it from the cache without bothering to + * Get the list of checkpoints for this file. If this is a read-only + * handle for a checkpoint or there's no reference in the metadata (the + * file is dead), then discard it from the cache without bothering to * write any dirty pages. */ - if ((ret = - __wt_meta_ckptlist_get(session, btree->name, &ckptbase)) != 0) { - if (ret == WT_NOTFOUND) + if (btree->checkpoint != NULL || (ret = __wt_meta_ckptlist_get( + session, btree->name, &ckptbase)) != 0) { + if (ret == 0 || ret == WT_NOTFOUND) ret = __wt_bt_cache_flush( session, NULL, WT_SYNC_DISCARD_NOWRITE, 0); goto err; @@ -354,8 +355,8 @@ __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) if (WT_META_TRACKING(session)) WT_CKPT_FOREACH(ckptbase, deleted) if (F_ISSET(deleted, WT_CKPT_DELETE)) - WT_ERR(__wt_session_lock_checkpoint(session, - deleted->name, WT_BTREE_EXCLUSIVE)); + WT_ERR(__wt_session_lock_checkpoint( + session, deleted->name)); /* Flush the file from the cache, creating the checkpoint. */ WT_ERR(__wt_bt_cache_flush( |