diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-03-20 17:10:56 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-03-20 17:10:56 +1100 |
commit | 098dafb29487c863d2ccef2d2cf4ec68140bd1a8 (patch) | |
tree | 3fe8ce1ad26b88ececc15379f0a937f762fc5271 | |
parent | df3d445d7fbed6fd0f198a13f85d454b00de51fc (diff) | |
download | mongo-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.c | 4 | ||||
-rw-r--r-- | src/include/btree.i | 26 | ||||
-rw-r--r-- | src/lsm/lsm_cursor.c | 5 | ||||
-rw-r--r-- | src/lsm/lsm_worker.c | 2 |
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( |