summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2015-01-13 17:38:01 +0000
committerKeith Bostic <keith@wiredtiger.com>2015-01-13 17:38:01 +0000
commit790b0b610bc85d3753f17404d2239831cf5ca627 (patch)
tree0b509a56b7e2284da67757ae398990ab5fa18f92
parentdb8272e0b2260a7d5b15e8f87e247bd898b7fab9 (diff)
downloadmongo-790b0b610bc85d3753f17404d2239831cf5ca627.tar.gz
Special-case the root; if it's putting cache pressure on the system, split it
even if there aren't many entries. Drop __split_deepen_per_child back to 100, that way if we split, we split big.
-rw-r--r--src/btree/bt_split.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index 393942362b4..2bae34b620b 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -9,13 +9,6 @@
#include "wt_internal.h"
/*
- * Tuning; global variables to allow the binary to be patched, we don't yet have
- * any real understanding of what might be useful to surface to applications.
- */
-static u_int __split_deepen_min_child = 10000;
-static u_int __split_deepen_per_child = 1000;
-
-/*
* Track allocation increments, matching the cache calculations, which add an
* estimate of allocation overhead to every object.
*/
@@ -175,26 +168,58 @@ __split_safe_free(WT_SESSION_IMPL *session, int exclusive, void *p, size_t s)
}
/*
+ * Tuning; global variables to allow the binary to be patched, we don't yet have
+ * any real understanding of what might be useful to surface to applications.
+ */
+static u_int __split_deepen_min_child = 10000;
+static u_int __split_deepen_per_child = 100;
+
+/*
* __split_should_deepen --
* Return if we should deepen the tree.
*/
static int
-__split_should_deepen(WT_SESSION_IMPL *session, WT_PAGE *page)
+__split_should_deepen(
+ WT_SESSION_IMPL *session, WT_REF *ref, uint32_t *childrenp)
{
WT_PAGE_INDEX *pindex;
+ WT_PAGE *page;
+
+ *childrenp = 0;
+ page = ref->page;
pindex = WT_INTL_INDEX_COPY(page);
/*
* Deepen the tree if the page's memory footprint is larger than the
* maximum size for a page in memory (presuambly putting eviction
- * pressure on the cache). Additionally, ensure the page has enough
- * entries to make it worth splitting, in the case of a set of large
- * keys, splitting won't help.
+ * pressure on the cache).
+ */
+ if (page->memory_footprint < S2BT(session)->maxmempage)
+ return (0);
+
+ /*
+ * Ensure the page has enough entries to make it worth splitting and
+ * we get a significant payback (in the case of a set of large keys,
+ * splitting won't help).
+ */
+ if (pindex->entries > __split_deepen_min_child) {
+ *childrenp = pindex->entries / __split_deepen_per_child;
+ return (1);
+ }
+
+ /*
+ * The root is a special-case: if it's putting cache pressure on the
+ * system, split it even if there are only a few entries, we can't
+ * push it out of memory. Sanity check: if the root page is too big
+ * with less than 100 keys, there are huge keys and/or a too-small
+ * cache, there's not much to do.
*/
- return (
- page->memory_footprint >= S2BT(session)->maxmempage &&
- pindex->entries > __split_deepen_min_child ? 1 : 0);
+ if (__wt_ref_is_root(ref) && pindex->entries > 100) {
+ *childrenp = pindex->entries / 10;
+ return (1);
+ }
+ return (0);
}
/*
@@ -361,7 +386,7 @@ __split_verify_intl_key_order(WT_SESSION_IMPL *session, WT_PAGE *page)
* Split an internal page in-memory, deepening the tree.
*/
static int
-__split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent)
+__split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children)
{
WT_DECL_RET;
WT_PAGE *child;
@@ -369,7 +394,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent)
WT_REF **alloc_refp;
WT_REF *child_ref, **child_refp, *parent_ref, **parent_refp, *ref;
size_t child_incr, parent_decr, parent_incr, size;
- uint32_t children, chunk, i, j, remain, slots;
+ uint32_t chunk, i, j, remain, slots;
int panic;
void *p;
@@ -379,12 +404,6 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent)
pindex = WT_INTL_INDEX_COPY(parent);
- /*
- * Create N children, unless we are dealing with a large page without
- * many entries, in which case split into the minimum number of pages.
- */
- children = pindex->entries / __split_deepen_per_child;
-
WT_STAT_FAST_CONN_INCR(session, cache_eviction_deepen);
WT_ERR(__wt_verbose(session, WT_VERB_SPLIT,
"%p: %" PRIu32 " elements, splitting into %" PRIu32 " children",
@@ -795,7 +814,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
WT_PAGE_INDEX *alloc_index, *pindex;
WT_REF **alloc_refp, *parent_ref;
size_t size;
- uint32_t i, j, parent_entries, result_entries;
+ uint32_t children, i, j, parent_entries, result_entries;
int complete, hazard, locked;
parent = NULL; /* -Wconditional-uninitialized */
@@ -955,9 +974,10 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
* Do the check here because we've just grown the parent page and
* are holding it locked.
*/
- if (ret == 0 && !exclusive && __split_should_deepen(session, parent))
+ if (ret == 0 && !exclusive &&
+ __split_should_deepen(session, parent_ref, &children))
WT_WITH_PAGE_INDEX(session,
- ret = __split_deepen(session, parent));
+ ret = __split_deepen(session, parent, children));
err: if (locked)
F_CLR_ATOMIC(parent, WT_PAGE_SPLITTING);