summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2013-03-20 17:10:56 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2013-03-20 17:10:56 +1100
commit098dafb29487c863d2ccef2d2cf4ec68140bd1a8 (patch)
tree3fe8ce1ad26b88ececc15379f0a937f762fc5271
parentdf3d445d7fbed6fd0f198a13f85d454b00de51fc (diff)
downloadmongo-098dafb29487c863d2ccef2d2cf4ec68140bd1a8.tar.gz
Fix several bugs in LSM:
* the logic for setting the "no eviction" flag on LSM chunks was reversed, causing unnecessary eviction once the cache became full; * calling session.checkpoint while writing to an LSM tree could confuse the logic around switching to new chunks; and * fix a possible NULL pointer indirection when switching chunks.
-rw-r--r--src/btree/bt_handle.c4
-rw-r--r--src/include/btree.i26
-rw-r--r--src/lsm/lsm_cursor.c5
-rw-r--r--src/lsm/lsm_worker.c2
4 files changed, 22 insertions, 15 deletions
diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c
index c41b002d995..0b13b4cee43 100644
--- a/src/btree/bt_handle.c
+++ b/src/btree/bt_handle.c
@@ -477,9 +477,9 @@ void
__wt_btree_evictable(WT_SESSION_IMPL *session, int on)
{
if (on)
- F_SET(session->btree, WT_BTREE_NO_EVICTION);
- else
F_CLR(session->btree, WT_BTREE_NO_EVICTION);
+ else
+ F_SET(session->btree, WT_BTREE_NO_EVICTION);
}
/*
diff --git a/src/include/btree.i b/src/include/btree.i
index 5ff4dcd2271..87dc15d1bb4 100644
--- a/src/include/btree.i
+++ b/src/include/btree.i
@@ -531,26 +531,30 @@ __wt_skip_choose_depth(void)
/*
* __wt_btree_size_overflow --
* Check if the size of an in-memory tree with a single leaf page is
- * over a specified maximum.
+ * over a specified maximum. If called on anything other than a simple
+ * tree with a single leaf page, returns true so the calling code will
+ * switch to a new tree.
*/
static inline int
__wt_btree_size_overflow(WT_SESSION_IMPL *session, uint32_t maxsize)
{
WT_BTREE *btree;
- WT_PAGE *child;
+ WT_PAGE *child, *root;
- /*
- * Only return true if:
- * - We have a valid btree
- * - The btree has only a single leaf page
- * - The single leaf page is in memory
- */
btree = session->btree;
- if (btree == NULL || btree->root_page->entries != 1 ||
- btree->root_page->u.intl.t->page == NULL)
+ root = btree->root_page;
+
+ if (btree == NULL || root == NULL ||
+ (child = root->u.intl.t->page) == NULL)
return (0);
- child = btree->root_page->u.intl.t->page;
+ /* Make sure this is a simple tree, or LSM should switch. */
+ if (!F_ISSET(btree, WT_BTREE_NO_EVICTION) ||
+ root->entries != 1 ||
+ root->u.intl.t->state != WT_REF_MEM ||
+ child->type != WT_PAGE_ROW_LEAF)
+ return (1);
+
return (child->memory_footprint > maxsize);
}
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 5b0574f56bb..bb886332f71 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -842,8 +842,11 @@ __clsm_put(
* in switching: if something went wrong, we should keep
* trying to switch.
*/
- if (ret == 0)
+ if (ret == 0) {
+ WT_SET_BTREE_IN_SESSION(session,
+ ((WT_CURSOR_BTREE *)primary)->btree);
__wt_btree_evictable(session, 1);
+ }
WT_TRET(__wt_rwunlock(session, lsm_tree->rwlock));
}
diff --git a/src/lsm/lsm_worker.c b/src/lsm/lsm_worker.c
index fa8ed1aa4bf..b85c8618965 100644
--- a/src/lsm/lsm_worker.c
+++ b/src/lsm/lsm_worker.c
@@ -341,9 +341,9 @@ __lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
if ((chunk = lsm_tree->old_chunks[i]) == NULL)
continue;
if (!locked) {
- locked = 1;
/* TODO: Do we need the lsm_tree lock for all drops? */
WT_ERR(__wt_writelock(session, lsm_tree->rwlock));
+ locked = 1;
}
if (F_ISSET(chunk, WT_LSM_CHUNK_BLOOM)) {
WT_WITH_SCHEMA_LOCK(session, ret = __wt_schema_drop(