diff options
author | Keith Bostic <keith@wiredtiger.com> | 2015-01-13 17:38:01 +0000 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2015-01-13 17:38:01 +0000 |
commit | 790b0b610bc85d3753f17404d2239831cf5ca627 (patch) | |
tree | 0b509a56b7e2284da67757ae398990ab5fa18f92 | |
parent | db8272e0b2260a7d5b15e8f87e247bd898b7fab9 (diff) | |
download | mongo-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.c | 70 |
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); |