summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-07-26 14:57:01 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-07-26 14:57:01 +1000
commit26b0d0e7a1fbcee401e4d32e003f483383b883e2 (patch)
treee93f7a79900659aaaf2ba0b32282fd4915b96587
parent15031c8608282e48e1bf382ab37b6ebc9cc8ef9a (diff)
downloadmongo-26b0d0e7a1fbcee401e4d32e003f483383b883e2.tar.gz
Checkpoint handles must be closed when they are overwritten.
closes #269
-rw-r--r--dist/s_define.list1
-rw-r--r--src/include/btree.h15
-rw-r--r--src/include/extern.h5
-rw-r--r--src/session/session_btree.c15
-rw-r--r--src/txn/txn_ckpt.c15
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(