summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoragorrod <alexg@wiredtiger.com>2012-09-24 16:03:44 -0700
committeragorrod <alexg@wiredtiger.com>2012-09-24 16:03:44 -0700
commitac35d03a739663465b058329f7388f3f770df52e (patch)
tree555aa5e331f441f8c2dea3df1c720fb537546b7b
parent085bcd3540ad3b79be220ef0fe10ca4da75972f1 (diff)
parentb7ca3fafc979c61064b832df96ca325cf703a792 (diff)
downloadmongo-ac35d03a739663465b058329f7388f3f770df52e.tar.gz
Merge pull request #336 from wiredtiger/lsm-checkpoint-open
Bug fixes for LSM open and handle locking
-rw-r--r--src/conn/conn_btree.c21
-rw-r--r--src/lsm/lsm_cursor.c18
-rw-r--r--src/lsm/lsm_tree.c5
-rw-r--r--src/lsm/lsm_worker.c2
-rw-r--r--src/schema/schema_drop.c11
5 files changed, 43 insertions, 14 deletions
diff --git a/src/conn/conn_btree.c b/src/conn/conn_btree.c
index 4f8b77e877e..090c9854d8b 100644
--- a/src/conn/conn_btree.c
+++ b/src/conn/conn_btree.c
@@ -422,14 +422,22 @@ __wt_conn_btree_close_all(WT_SESSION_IMPL *session, const char *name)
WT_DECL_RET;
conn = S2C(session);
- saved_btree = session->btree;
WT_ASSERT(session, F_ISSET(session, WT_SESSION_SCHEMA_LOCKED));
+ /*
+ * Make sure the caller's handle is tracked, so it will be unlocked
+ * even if we failed to get all of the remaining handles we need.
+ */
+ if ((saved_btree = session->btree) != NULL && WT_META_TRACKING(session))
+ WT_ERR(__wt_meta_track_handle_lock(session, 0));
+
TAILQ_FOREACH(btree, &conn->btqh, q) {
if (strcmp(btree->name, name) != 0)
continue;
+ WT_SET_BTREE_IN_SESSION(session, btree);
+
/*
* The caller may have this tree locked to prevent
* concurrent schema operations.
@@ -439,12 +447,10 @@ __wt_conn_btree_close_all(WT_SESSION_IMPL *session, const char *name)
else {
WT_ERR(__wt_try_writelock(session, btree->rwlock));
F_SET(btree, WT_BTREE_EXCLUSIVE);
+ if (WT_META_TRACKING(session))
+ WT_ERR(__wt_meta_track_handle_lock(session, 0));
}
- session->btree = btree;
- if (WT_META_TRACKING(session))
- WT_ERR(__wt_meta_track_handle_lock(session, 0));
-
/*
* We have an exclusive lock, which means there are no
* cursors open at this point. Close the handle, if
@@ -467,12 +473,13 @@ __wt_conn_btree_close_all(WT_SESSION_IMPL *session, const char *name)
if (!WT_META_TRACKING(session))
WT_TRET(__wt_session_release_btree(session));
- session->btree = NULL;
+ WT_CLEAR_BTREE_IN_SESSION(session);
WT_ERR(ret);
}
-err: return (ret);
+err: WT_CLEAR_BTREE_IN_SESSION(session);
+ return (ret);
}
/*
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index f619af0ef86..4294a97e35f 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -113,7 +113,8 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm)
WT_LSM_CHUNK *chunk;
WT_LSM_TREE *lsm_tree;
WT_SESSION_IMPL *session;
- const char *ckpt_cfg[] = { "checkpoint=WiredTigerCheckpoint", NULL };
+ const char *ckpt_cfg[] = API_CONF_DEFAULTS(session, open_cursor,
+ "checkpoint=WiredTigerCheckpoint");
int i, nchunks;
session = (WT_SESSION_IMPL *)clsm->iface.session;
@@ -152,9 +153,20 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm)
* Once all cursors switch, the in-memory tree can be evicted.
*/
chunk = lsm_tree->chunk[i];
- WT_ERR(__wt_curfile_open(session,
+ ret = __wt_curfile_open(session,
chunk->uri, &clsm->iface,
- F_ISSET(chunk, WT_LSM_CHUNK_ONDISK) ? ckpt_cfg : NULL, cp));
+ F_ISSET(chunk, WT_LSM_CHUNK_ONDISK) ? ckpt_cfg : NULL, cp);
+
+ /*
+ * XXX kludge: we may have an empty chunk where no checkpoint
+ * was written. If so, try to open the ordinary handle on that
+ * chunk instead.
+ */
+ if (ret == WT_NOTFOUND && F_ISSET(chunk, WT_LSM_CHUNK_ONDISK))
+ ret = __wt_curfile_open(session,
+ chunk->uri, &clsm->iface, NULL, cp);
+ WT_ERR(ret);
+
if (chunk->bloom_uri != NULL && !F_ISSET(clsm, WT_CLSM_MERGE))
WT_ERR(__wt_bloom_open(session, chunk->bloom_uri,
lsm_tree->bloom_bit_count,
diff --git a/src/lsm/lsm_tree.c b/src/lsm/lsm_tree.c
index 45e60621dd4..49ccdd07c4f 100644
--- a/src/lsm/lsm_tree.c
+++ b/src/lsm/lsm_tree.c
@@ -232,7 +232,7 @@ __wt_lsm_tree_create(WT_SESSION_IMPL *session,
lsm_tree->file_config = __wt_buf_steal(session, buf, NULL);
/* Create the first chunk and flush the metadata. */
- WT_ERR(__wt_lsm_tree_switch(session, lsm_tree));
+ WT_ERR(__wt_lsm_meta_write(session, lsm_tree));
/* Discard our partially populated handle. */
__lsm_tree_discard(session, lsm_tree);
@@ -273,6 +273,9 @@ __lsm_tree_open(
lsm_tree->filename = lsm_tree->name + strlen("lsm:");
WT_ERR(__wt_lsm_meta_read(session, lsm_tree));
+ if (lsm_tree->nchunks == 0)
+ WT_ERR(__wt_lsm_tree_switch(session, lsm_tree));
+
/* Set the generation number so cursors are opened on first usage. */
lsm_tree->dsk_gen = 1;
diff --git a/src/lsm/lsm_worker.c b/src/lsm/lsm_worker.c
index 383098ac53e..c8608463fb0 100644
--- a/src/lsm/lsm_worker.c
+++ b/src/lsm/lsm_worker.c
@@ -22,7 +22,7 @@ __wt_lsm_worker(void *arg)
WT_LSM_CHUNK *chunk, **chunk_array;
WT_LSM_TREE *lsm_tree;
WT_SESSION_IMPL *session;
- const char *cfg[] = { "name=,drop=", NULL };
+ const char *cfg[] = API_CONF_DEFAULTS(session, checkpoint, NULL);
size_t chunk_alloc;
int i, nchunks, progress;
diff --git a/src/schema/schema_drop.c b/src/schema/schema_drop.c
index f16b76286e3..cea49360e2c 100644
--- a/src/schema/schema_drop.c
+++ b/src/schema/schema_drop.c
@@ -81,9 +81,13 @@ __drop_tree(
WT_ERR(__wt_scr_alloc(session, 0, &buf));
WT_ERR(__wt_buf_set(
session, buf, btree->name, strlen(btree->name) + 1));
- WT_ERR(__drop_file(session, buf->data, force, cfg));
+ WT_TRET(__drop_file(session, buf->data, force, cfg));
-err: __wt_scr_free(&buf);
+ if (0) {
+err: session->btree = btree;
+ (void)__wt_session_release_btree(session);
+ }
+ __wt_scr_free(&buf);
return (ret);
}
@@ -241,6 +245,9 @@ __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
WT_RET(__wt_meta_track_on(session));
+ /* Be careful to ignore any btree handle in our caller. */
+ WT_CLEAR_BTREE_IN_SESSION(session);
+
if (WT_PREFIX_MATCH(uri, "colgroup:"))
ret = __drop_colgroup(session, uri, force, cfg);
else if (WT_PREFIX_MATCH(uri, "file:"))