summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2013-05-23 10:03:20 -0400
committerKeith Bostic <keith@wiredtiger.com>2013-05-23 10:03:20 -0400
commit1f8b2a305f5628c50b2b186bfa5476a5d8f65563 (patch)
tree76bc29a796d4a5940c0a647b4f6330a3513f6c44 /src
parent61df0b046cddb5a79ff5d8b84e43e8b7af39dbba (diff)
downloadmongo-1f8b2a305f5628c50b2b186bfa5476a5d8f65563.tar.gz
LSM trees don't support named checkpoints: disallow attempts, add
documentation, and change test/format to not attempt it. Ref #546.
Diffstat (limited to 'src')
-rw-r--r--src/docs/checkpoints.dox14
-rw-r--r--src/include/wiredtiger.in11
-rw-r--r--src/txn/txn_ckpt.c86
3 files changed, 82 insertions, 29 deletions
diff --git a/src/docs/checkpoints.dox b/src/docs/checkpoints.dox
index 34b4aa52685..29a58c03b2a 100644
--- a/src/docs/checkpoints.dox
+++ b/src/docs/checkpoints.dox
@@ -35,13 +35,13 @@ Checkpoints share file blocks, and dropping a checkpoint may or may not
make file blocks available for re-use, depending on whether the dropped
checkpoint contained the last reference to a file block.
-Checkpoints may optionally be given names by the application.
-Checkpoints named by the application persist until explicitly dropped
-or the application creates a new checkpoint with the same name.
-Creating a new named checkpoint drops any previous checkpoint with the
-same name; if a previous checkpoint cannot be dropped (either because a
-cursor is reading from the previous checkpoint, or hot backups are in
-progress), the checkpoint will fail.
+Checkpoints that do not include LSM trees may optionally be given names
+by the application. Checkpoints named by the application persist until
+explicitly dropped or the application creates a new checkpoint with the
+same name. Creating a new named checkpoint drops any previous
+checkpoint with the same name; if a previous checkpoint cannot be
+dropped (either because a cursor is reading from the previous
+checkpoint, or hot backups are in progress), the checkpoint will fail.
Internal checkpoints (that is, checkpoints not named by the application)
use the reserved name "WiredTigerCheckpoint". Applications can open the
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index f3c63b8de20..9ea2e41ba59 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1028,11 +1028,12 @@ struct __wt_session {
* drop all checkpoints before and including the named checkpoint.
* Checkpoints cannot be dropped while a hot backup is in progress or if
* open in a cursor., a list of strings; default empty.}
- * @config{force, checkpoints may be skipped if the underlying object
- * has not been modified\, this option forces the checkpoint., a boolean
- * flag; default \c false.}
- * @config{name, if non-empty\, specify a name for the checkpoint., a
- * string; default empty.}
+ * @config{force, by default\, checkpoints may be skipped if the
+ * underlying object has not been modified\, this option forces the
+ * checkpoint., a boolean flag; default \c false.}
+ * @config{name, if non-empty\, specify a name for the checkpoint (note
+ * that checkpoints including LSM trees may not be named)., a string;
+ * default empty.}
* @config{target, if non-empty\, checkpoint the list of objects., a
* list of strings; default empty.}
* @configend
diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c
index b4c6e2c1084..965356dcee2 100644
--- a/src/txn/txn_ckpt.c
+++ b/src/txn/txn_ckpt.c
@@ -11,6 +11,50 @@ static int __checkpoint_sync(WT_SESSION_IMPL *, const char *[]);
static int __checkpoint_write_leaves(WT_SESSION_IMPL *, const char *[]);
/*
+ * __checkpoint_lsm_check --
+ * Check for an attempt to name a checkpoint that includes an LSM tree.
+ */
+static int
+__checkpoint_lsm_check(WT_SESSION_IMPL *session, const char *uri)
+{
+ WT_CURSOR *cursor;
+ WT_DECL_RET;
+ int cmp, fail;
+
+ cursor = NULL;
+ fail = 0;
+
+ /*
+ * This function exists as a place to hang this comment: LSM trees don't
+ * support named checkpoints. If a target list for the checkpoint is
+ * provided, this function is called with each target list entry; check
+ * the entry to make sure it's not an LSM tree. If no target list is
+ * provided, confirm the metadata file contains no LSM trees.
+ */
+ if (uri == NULL) {
+ WT_ERR(__wt_metadata_cursor(session, NULL, &cursor));
+ cursor->set_key(cursor, "lsm:");
+ if ((ret = cursor->search_near(cursor, &cmp)) == 0 && cmp < 0)
+ ret = cursor->next(cursor);
+ if (ret == 0) {
+ WT_ERR(cursor->get_key(cursor, &uri));
+ if (WT_PREFIX_MATCH(uri, "lsm:"))
+ fail = 1;
+ } else
+ WT_ERR_NOTFOUND_OK(ret);
+ } else if (WT_PREFIX_MATCH(uri, "lsm:"))
+ fail = 1;
+
+ if (fail)
+ WT_ERR_MSG(session, EINVAL,
+ "LSM trees do not support named checkpoints");
+
+err: if (cursor != NULL)
+ WT_ERR(cursor->close(cursor));
+ return (ret);
+}
+
+/*
* __checkpoint_apply --
* Apply an operation to all files involved in a checkpoint.
*/
@@ -22,10 +66,14 @@ __checkpoint_apply(WT_SESSION_IMPL *session, const char *cfg[],
WT_CONFIG_ITEM cval, k, v;
WT_DECL_ITEM(tmp);
WT_DECL_RET;
- int ckpt_closed, target_list;
+ int ckpt_closed, named, target_list;
target_list = 0;
+ /* Flag if this is a named checkpoint. */
+ WT_ERR(__wt_config_gets(session, cfg, "name", &cval));
+ named = cval.len != 0;
+
/* Step through the list of targets and checkpoint each one. */
WT_ERR(__wt_config_gets(session, cfg, "target", &cval));
WT_ERR(__wt_config_subinit(session, &targetconf, &cval));
@@ -37,9 +85,13 @@ __checkpoint_apply(WT_SESSION_IMPL *session, const char *cfg[],
if (v.len != 0)
WT_ERR_MSG(session, EINVAL,
- "invalid checkpoint target \"%s\": URIs may "
- "require quoting",
- (const char *)tmp->data);
+ "invalid checkpoint target %.*s: URIs may require "
+ "quoting",
+ (int)cval.len, (char *)cval.str);
+
+ /* LSM trees don't support named checkpoints. */
+ if (named)
+ WT_ERR(__checkpoint_lsm_check(session, k.str));
WT_ERR(__wt_buf_fmt(session, tmp, "%.*s", (int)k.len, k.str));
if ((ret = __wt_schema_worker(
@@ -49,10 +101,14 @@ __checkpoint_apply(WT_SESSION_IMPL *session, const char *cfg[],
WT_ERR_NOTFOUND_OK(ret);
if (!target_list) {
+ /* LSM trees don't support named checkpoints. */
+ if (named)
+ WT_ERR(__checkpoint_lsm_check(session, NULL));
+
/*
- * Possible checkpoint name. If checkpoints are named or we're
- * dropping checkpoints, checkpoint both open and closed files;
- * else, we only checkpoint open files.
+ * If the checkpoint is named or we're dropping checkpoints, we
+ * checkpoint both open and closed files; else, only checkpoint
+ * open files.
*
* XXX
* We don't optimize unnamed checkpoints of a list of targets,
@@ -60,14 +116,11 @@ __checkpoint_apply(WT_SESSION_IMPL *session, const char *cfg[],
* quiescent and don't need a checkpoint, believing applications
* unlikely to checkpoint a list of closed targets.
*/
- cval.len = 0;
- ckpt_closed = 0;
- WT_ERR(__wt_config_gets(session, cfg, "name", &cval));
- if (cval.len != 0)
- ckpt_closed = 1;
- WT_ERR(__wt_config_gets(session, cfg, "drop", &cval));
- if (cval.len != 0)
- ckpt_closed = 1;
+ ckpt_closed = named;
+ if (!ckpt_closed) {
+ WT_ERR(__wt_config_gets(session, cfg, "drop", &cval));
+ ckpt_closed = cval.len != 0;
+ }
WT_ERR(ckpt_closed ?
__wt_meta_btree_apply(session, op, cfg) :
__wt_conn_btree_apply(session, op, cfg));
@@ -680,8 +733,7 @@ __checkpoint_write_leaves(WT_SESSION_IMPL *session, const char *cfg[])
WT_UNUSED(cfg);
if (S2BT(session)->modified)
- WT_RET(__wt_bt_cache_op(
- session, NULL, WT_SYNC_WRITE_LEAVES));
+ WT_RET(__wt_bt_cache_op(session, NULL, WT_SYNC_WRITE_LEAVES));
return (0);
}