summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/include/btree.i
diff options
context:
space:
mode:
authorRamon Fernandez <ramon@mongodb.com>2016-08-26 18:28:48 -0400
committerRamon Fernandez <ramon@mongodb.com>2016-08-26 18:28:48 -0400
commitf2a613a41d6ad7b5a1b66087e386380d38e50599 (patch)
tree4843fb7b6a835e72046142046e9364f7d7dda992 /src/third_party/wiredtiger/src/include/btree.i
parent7614c0eb2449eb4ec22d21b677177124d61f1888 (diff)
downloadmongo-f2a613a41d6ad7b5a1b66087e386380d38e50599.tar.gz
Import wiredtiger: 2566118fc68b0124187e806bed52eb7cdbcb1be0 from branch mongodb-3.4
ref: 34182ad..2566118fc6 for: 3.3.12 WT-2631 nullptr is passed for parameters marked with attribute non-null WT-2638 ftruncate may not be supported WT-2645 wt dump: push the complexity of collecting metadata into a dump cursor WT-2678 The metadata should not imply that an empty value is true WT-2695 Integrate s390x accelerated crc32c support WT-2719 add fuzz testing for WiredTiger options and reconfiguration. WT-2734 Improve documentation of eviction behavior WT-2766 Don't count eviction of lookaside file pages for the purpose of checking stuck cache WT-2783 wtperf multi-btree.wtperf dumps core on Mac WT-2787 Include src/include/wiredtiger_ext.h is problematic WT-2795 Update documentation around read-only configuration WT-2807 Switch Jenkins performance tests to tcmalloc WT-2813 small cache usage stuck even with large cache WT-2814 Enhance wtperf to support single-op truncate mode WT-2816 Improve WiredTiger eviction performance WT-2817 Investigate performance regression in develop, add workload to wtperf/runners WT-2818 The page visibility check when queuing pages for eviction is overly restrictive WT-2820 add gcc warn_unused_result attribute WT-2822 panic mutex and other functions that cannot fail WT-2823 support file handles without a truncate method WT-2826 clang38 false positive on uninitialized variable. WT-2827 checkpoint log_size configuration improvements WT-2828 Make long wtperf tests reflect mongoDB usage WT-2829 Switch automated testing to use enable-strict configure option WT-2832 Python test uses hard-coded temporary directory WT-2834 Join cursor: discrepancy with bloom filters WT-2835 WT_CONNECTION.leak-memory can skip memory map and cache cleanup WT-2838 Don't free session handles on close if leak memory is configured WT-2839 lint: Ignoring return value of function WT-2840 clang analysis: garbage values WT-2841 Jenkins Valgrind runner is reporting errors in test wt2719_reconfig WT-2843 Fix a bug in recovery if there is no filesystem truncate support WT-2846 Several bugs related to reconfiguring eviction server at runtime WT-2847 Merge fair locks into read/write locks. WT-2850 clang 4.1 attribute warnings when building WT-2853 Multi threaded reader writer example shows temporary slowdown or lockup WT-2857 POSIX ftruncate calls should be #ifdef'd HAVE_FTRUNCATE WT-2862 Fix lint error in test case for forced eviction with multiple cursors WT-2863 Support UTF-8 paths on Windows
Diffstat (limited to 'src/third_party/wiredtiger/src/include/btree.i')
-rw-r--r--src/third_party/wiredtiger/src/include/btree.i158
1 files changed, 96 insertions, 62 deletions
diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i
index 3234ad1ed41..1ca6426eef6 100644
--- a/src/third_party/wiredtiger/src/include/btree.i
+++ b/src/third_party/wiredtiger/src/include/btree.i
@@ -61,18 +61,29 @@ __wt_btree_block_free(
static inline uint64_t
__wt_btree_bytes_inuse(WT_SESSION_IMPL *session)
{
+ WT_BTREE *btree;
WT_CACHE *cache;
- uint64_t bytes_inuse;
+ btree = S2BT(session);
cache = S2C(session)->cache;
- /* Adjust the cache size to take allocation overhead into account. */
- bytes_inuse = S2BT(session)->bytes_inmem;
- if (cache->overhead_pct != 0)
- bytes_inuse +=
- (bytes_inuse * (uint64_t)cache->overhead_pct) / 100;
+ return (__wt_cache_bytes_plus_overhead(cache, btree->bytes_inmem));
+}
+
+/*
+ * __wt_btree_dirty_leaf_inuse --
+ * Return the number of bytes in use by dirty leaf pages.
+ */
+static inline uint64_t
+__wt_btree_dirty_leaf_inuse(WT_SESSION_IMPL *session)
+{
+ WT_BTREE *btree;
+ WT_CACHE *cache;
+
+ btree = S2BT(session);
+ cache = S2C(session)->cache;
- return (bytes_inuse);
+ return (__wt_cache_bytes_plus_overhead(cache, btree->bytes_dirty_leaf));
}
/*
@@ -82,18 +93,24 @@ __wt_btree_bytes_inuse(WT_SESSION_IMPL *session)
static inline void
__wt_cache_page_inmem_incr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size)
{
+ WT_BTREE *btree;
WT_CACHE *cache;
WT_ASSERT(session, size < WT_EXABYTE);
-
+ btree = S2BT(session);
cache = S2C(session)->cache;
- (void)__wt_atomic_add64(&S2BT(session)->bytes_inmem, size);
+
+ (void)__wt_atomic_add64(&btree->bytes_inmem, size);
(void)__wt_atomic_add64(&cache->bytes_inmem, size);
(void)__wt_atomic_addsize(&page->memory_footprint, size);
if (__wt_page_is_modified(page)) {
(void)__wt_atomic_addsize(&page->modify->bytes_dirty, size);
- (void)__wt_atomic_add64(WT_PAGE_IS_INTERNAL(page) ?
- &cache->bytes_dirty_intl : &cache->bytes_dirty_leaf, size);
+ if (WT_PAGE_IS_INTERNAL(page))
+ (void)__wt_atomic_add64(&cache->bytes_dirty_intl, size);
+ else {
+ (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
+ (void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size);
+ }
}
/* Track internal size in cache. */
if (WT_PAGE_IS_INTERNAL(page))
@@ -157,6 +174,22 @@ __wt_cache_decr_check_uint64(
}
/*
+ * __wt_cache_decr_zero_uint64 --
+ * Decrement a uint64_t cache value and zero it on underflow.
+ */
+static inline void
+__wt_cache_decr_zero_uint64(
+ WT_SESSION_IMPL *session, uint64_t *vp, size_t v, const char *fld)
+{
+ if (__wt_atomic_sub64(vp, v) < WT_EXABYTE)
+ return;
+
+ __wt_errx(
+ session, "%s went negative: decrementing %" WT_SIZET_FMT, fld, v);
+ *vp = 0;
+}
+
+/*
* __wt_cache_page_byte_dirty_decr --
* Decrement the page's dirty byte count, guarding from underflow.
*/
@@ -164,17 +197,14 @@ static inline void
__wt_cache_page_byte_dirty_decr(
WT_SESSION_IMPL *session, WT_PAGE *page, size_t size)
{
+ WT_BTREE *btree;
WT_CACHE *cache;
- const char *destname;
- uint64_t *dest;
size_t decr, orig;
int i;
+ btree = S2BT(session);
cache = S2C(session)->cache;
- dest = WT_PAGE_IS_INTERNAL(page) ?
- &cache->bytes_dirty_intl : &cache->bytes_dirty_leaf;
- destname = WT_PAGE_IS_INTERNAL(page) ?
- "WT_CACHE.bytes_dirty_intl" : "WT_CACHE.bytes_dirty_leaf";
+ decr = 0; /* [-Wconditional-uninitialized] */
/*
* We don't have exclusive access and there are ways of decrementing the
@@ -201,11 +231,21 @@ __wt_cache_page_byte_dirty_decr(
orig = page->modify->bytes_dirty;
decr = WT_MIN(size, orig);
if (__wt_atomic_cassize(
- &page->modify->bytes_dirty, orig, orig - decr)) {
- __wt_cache_decr_check_uint64(
- session, dest, decr, destname);
+ &page->modify->bytes_dirty, orig, orig - decr))
break;
- }
+ }
+
+ if (i == 5)
+ return;
+
+ if (WT_PAGE_IS_INTERNAL(page))
+ __wt_cache_decr_check_uint64(session, &cache->bytes_dirty_intl,
+ decr, "WT_CACHE.bytes_dirty_intl");
+ else {
+ __wt_cache_decr_check_uint64(session, &btree->bytes_dirty_leaf,
+ decr, "WT_BTREE.bytes_dirty_leaf");
+ __wt_cache_decr_check_uint64(session, &cache->bytes_dirty_leaf,
+ decr, "WT_CACHE.bytes_dirty_leaf");
}
}
@@ -244,20 +284,26 @@ __wt_cache_page_inmem_decr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size)
static inline void
__wt_cache_dirty_incr(WT_SESSION_IMPL *session, WT_PAGE *page)
{
+ WT_BTREE *btree;
WT_CACHE *cache;
size_t size;
+ btree = S2BT(session);
cache = S2C(session)->cache;
- (void)__wt_atomic_add64(WT_PAGE_IS_INTERNAL(page) ?
- &cache->pages_dirty_intl : &cache->pages_dirty_leaf, 1);
/*
* Take care to read the memory_footprint once in case we are racing
* with updates.
*/
size = page->memory_footprint;
- (void)__wt_atomic_add64(WT_PAGE_IS_INTERNAL(page) ?
- &cache->bytes_dirty_intl : &cache->bytes_dirty_leaf, size);
+ if (WT_PAGE_IS_INTERNAL(page)) {
+ (void)__wt_atomic_add64(&cache->bytes_dirty_intl, size);
+ (void)__wt_atomic_add64(&cache->pages_dirty_intl, 1);
+ } else {
+ (void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size);
+ (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
+ (void)__wt_atomic_add64(&cache->pages_dirty_leaf, 1);
+ }
(void)__wt_atomic_addsize(&page->modify->bytes_dirty, size);
}
@@ -271,19 +317,15 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page)
{
WT_CACHE *cache;
WT_PAGE_MODIFY *modify;
- uint64_t *pages_dirty;
cache = S2C(session)->cache;
- pages_dirty = WT_PAGE_IS_INTERNAL(page) ?
- &cache->pages_dirty_intl : &cache->pages_dirty_leaf;
- if (*pages_dirty < 1) {
- __wt_errx(session,
- "cache eviction dirty-page decrement failed: dirty page"
- "count went negative");
- *pages_dirty = 0;
- } else
- (void)__wt_atomic_sub64(pages_dirty, 1);
+ if (WT_PAGE_IS_INTERNAL(page))
+ __wt_cache_decr_zero_uint64(session,
+ &cache->pages_dirty_intl, 1, "dirty internal page count");
+ else
+ __wt_cache_decr_zero_uint64(session,
+ &cache->pages_dirty_leaf, 1, "dirty leaf page count");
modify = page->modify;
if (modify != NULL && modify->bytes_dirty != 0)
@@ -326,16 +368,12 @@ __wt_cache_page_image_incr(WT_SESSION_IMPL *session, uint32_t size)
static inline void
__wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
{
+ WT_BTREE *btree;
WT_CACHE *cache;
WT_PAGE_MODIFY *modify;
- uint64_t *dest;
- const char *destname;
+ btree = S2BT(session);
cache = S2C(session)->cache;
- dest = WT_PAGE_IS_INTERNAL(page) ?
- &cache->bytes_dirty_intl : &cache->bytes_dirty_leaf;
- destname = WT_PAGE_IS_INTERNAL(page) ?
- "WT_CACHE.bytes_dirty_intl" : "WT_CACHE.bytes_dirty_leaf";
modify = page->modify;
/* Update the bytes in-memory to reflect the eviction. */
@@ -352,14 +390,18 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
/* Update the cache's dirty-byte count. */
if (modify != NULL && modify->bytes_dirty != 0) {
- if ((size_t)*dest < modify->bytes_dirty) {
- __wt_errx(session,
- "%s decrement failed: "
- "dirty byte count went negative", destname);
- *dest = 0;
- } else
- __wt_cache_decr_check_uint64(session, dest,
- modify->bytes_dirty, destname);
+ if (WT_PAGE_IS_INTERNAL(page))
+ __wt_cache_decr_zero_uint64(session,
+ &cache->bytes_dirty_intl,
+ modify->bytes_dirty, "WT_CACHE.bytes_dirty_intl");
+ else {
+ __wt_cache_decr_zero_uint64(session,
+ &cache->bytes_dirty_leaf,
+ modify->bytes_dirty, "WT_CACHE.bytes_dirty_leaf");
+ __wt_cache_decr_zero_uint64(session,
+ &btree->bytes_dirty_leaf,
+ modify->bytes_dirty, "WT_BTREE.bytes_dirty_leaf");
+ }
}
/* Update pages and bytes evicted. */
@@ -1190,7 +1232,7 @@ __wt_page_can_evict(
* previous version might be referenced by an internal page already
* been written in the checkpoint, leaving the checkpoint inconsistent.
*/
- if (btree->checkpointing != WT_CKPT_OFF && modified) {
+ if (modified && btree->checkpointing != WT_CKPT_OFF) {
WT_STAT_FAST_CONN_INCR(session, cache_eviction_checkpoint);
WT_STAT_FAST_DATA_INCR(session, cache_eviction_checkpoint);
return (false);
@@ -1217,20 +1259,12 @@ __wt_page_can_evict(
F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_BLOCK))
return (false);
- /* If the cache is stuck, try anything else. */
- if (F_ISSET(S2C(session)->cache, WT_CACHE_STUCK))
- return (true);
-
/*
- * If the oldest transaction hasn't changed since the last time
- * this page was written, it's unlikely we can make progress.
- * Similarly, if the most recent update on the page is not yet
- * globally visible, eviction will fail. These heuristics
- * attempt to avoid repeated attempts to evict the same page.
+ * If the page is clean but has modifications that
+ * appear too new to evict, skip it.
*/
- if (modified &&
- (mod->last_oldest_id == __wt_txn_oldest_id(session) ||
- !__wt_txn_visible_all(session, mod->update_txn)))
+ if (!modified && mod != NULL &&
+ !__wt_txn_visible_all(session, mod->rec_max_txn))
return (false);
return (true);