diff options
author | Keith Bostic <keith@wiredtiger.com> | 2013-05-23 10:03:20 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2013-05-23 10:03:20 -0400 |
commit | 1f8b2a305f5628c50b2b186bfa5476a5d8f65563 (patch) | |
tree | 76bc29a796d4a5940c0a647b4f6330a3513f6c44 /src | |
parent | 61df0b046cddb5a79ff5d8b84e43e8b7af39dbba (diff) | |
download | mongo-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.dox | 14 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 11 | ||||
-rw-r--r-- | src/txn/txn_ckpt.c | 86 |
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); } |