diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-24 14:48:18 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-24 14:48:18 +1100 |
commit | 92b95f55d99a88d94aa5c14da6e8bd4f13408e24 (patch) | |
tree | 1f7e3bcf449f8d676baf21c4d0dd93c605e68f3d | |
parent | ce89b608835561b11ce4e525a5ebdad86558f115 (diff) | |
parent | 303b826d41cf42b952517e4cec2a1003fd860e60 (diff) | |
download | mongo-92b95f55d99a88d94aa5c14da6e8bd4f13408e24.tar.gz |
Merge branch 'develop' into statistics-sources-handle-overwrite
-rw-r--r-- | src/btree/bt_compact.c | 7 | ||||
-rw-r--r-- | src/btree/bt_page.c | 17 | ||||
-rw-r--r-- | src/btree/bt_sync.c | 7 | ||||
-rw-r--r-- | src/evict/evict_file.c | 11 | ||||
-rw-r--r-- | src/evict/evict_lru.c | 38 | ||||
-rw-r--r-- | src/include/extern.h | 2 | ||||
-rw-r--r-- | src/log/log_slot.c | 3 |
7 files changed, 51 insertions, 34 deletions
diff --git a/src/btree/bt_compact.c b/src/btree/bt_compact.c index d8b3a638de3..1528d65b8c8 100644 --- a/src/btree/bt_compact.c +++ b/src/btree/bt_compact.c @@ -76,7 +76,7 @@ __wt_compact(WT_SESSION_IMPL *session, const char *cfg[]) WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_REF *ref; - int block_manager_begin, skip; + int block_manager_begin, evict_reset, skip; WT_UNUSED(cfg); @@ -133,8 +133,9 @@ __wt_compact(WT_SESSION_IMPL *session, const char *cfg[]) * then let eviction continue; */ conn->compact_in_memory_pass = 1; - WT_ERR(__wt_evict_file_exclusive_on(session)); - __wt_evict_file_exclusive_off(session); + WT_ERR(__wt_evict_file_exclusive_on(session, &evict_reset)); + if (evict_reset) + __wt_evict_file_exclusive_off(session); /* Start compaction. */ WT_ERR(bm->compact_start(bm, session)); diff --git a/src/btree/bt_page.c b/src/btree/bt_page.c index 2f2ce4cf4f7..b5140beb792 100644 --- a/src/btree/bt_page.c +++ b/src/btree/bt_page.c @@ -129,15 +129,24 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags __evict_force_check(session, page, flags)) { ++force_attempts; ret = __wt_page_release_evict(session, ref); + /* If forced eviction fails, stall. */ if (ret == EBUSY) { - /* If forced eviction fails, stall. */ ret = 0; wait_cnt += 1000; + WT_STAT_FAST_CONN_INCR(session, + page_forcible_evict_blocked); + break; } else WT_RET(ret); - WT_STAT_FAST_CONN_INCR( - session, page_forcible_evict_blocked); - break; + + /* + * The result of a successful forced eviction + * is a page-state transition (potentially to + * an in-memory page we can use, or a restart + * return for our caller), continue the outer + * page-acquisition loop. + */ + continue; } /* Check if we need an autocommit transaction. */ diff --git a/src/btree/bt_sync.c b/src/btree/bt_sync.c index a75af03d8c8..d925eefc2fe 100644 --- a/src/btree/bt_sync.c +++ b/src/btree/bt_sync.c @@ -25,6 +25,7 @@ __sync_file(WT_SESSION_IMPL *session, int syncop) uint64_t internal_bytes, leaf_bytes; uint64_t internal_pages, leaf_pages; uint32_t flags; + int evict_reset; btree = S2BT(session); @@ -99,11 +100,11 @@ __sync_file(WT_SESSION_IMPL *session, int syncop) * eviction to complete. */ btree->checkpointing = 1; + WT_FULL_BARRIER(); - if (!F_ISSET(btree, WT_BTREE_NO_EVICTION)) { - WT_ERR(__wt_evict_file_exclusive_on(session)); + WT_ERR(__wt_evict_file_exclusive_on(session, &evict_reset)); + if (evict_reset) __wt_evict_file_exclusive_off(session); - } /* Write all dirty in-cache pages. */ flags |= WT_READ_NO_EVICT; diff --git a/src/evict/evict_file.c b/src/evict/evict_file.c index 910aef070ca..9e39fcc7a2c 100644 --- a/src/evict/evict_file.c +++ b/src/evict/evict_file.c @@ -15,21 +15,16 @@ int __wt_evict_file(WT_SESSION_IMPL *session, int syncop) { - WT_BTREE *btree; WT_DECL_RET; WT_PAGE *page; WT_REF *next_ref, *ref; - int eviction_enabled; - - btree = S2BT(session); - eviction_enabled = !F_ISSET(btree, WT_BTREE_NO_EVICTION); + int evict_reset; /* * We need exclusive access to the file -- disable ordinary eviction * and drain any blocks already queued. */ - if (eviction_enabled) - WT_RET(__wt_evict_file_exclusive_on(session)); + WT_RET(__wt_evict_file_exclusive_on(session, &evict_reset)); /* Make sure the oldest transaction ID is up-to-date. */ __wt_txn_update_oldest(session); @@ -140,7 +135,7 @@ err: /* On error, clear any left-over tree walk. */ session, next_ref, WT_READ_NO_EVICT)); } - if (eviction_enabled) + if (evict_reset) __wt_evict_file_exclusive_off(session); return (ret); diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c index 83a9aa5c8c5..78c34f0267e 100644 --- a/src/evict/evict_lru.c +++ b/src/evict/evict_lru.c @@ -653,7 +653,7 @@ __wt_evict_page(WT_SESSION_IMPL *session, WT_REF *ref) * blocks queued for eviction. */ int -__wt_evict_file_exclusive_on(WT_SESSION_IMPL *session) +__wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, int *evict_resetp) { WT_BTREE *btree; WT_CACHE *cache; @@ -664,6 +664,15 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session) cache = S2C(session)->cache; /* + * If the file isn't evictable, there's no work to do. + */ + if (F_ISSET(btree, WT_BTREE_NO_EVICTION)) { + *evict_resetp = 0; + return (0); + } + *evict_resetp = 1; + + /* * Hold the walk lock to set the "no eviction" flag: no new pages from * the file will be queued for eviction after this point. */ @@ -1072,34 +1081,37 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp, uint32_t flags) WT_PAGE_MODIFY *mod; uint64_t pages_walked; uint32_t walk_flags; - int internal_pages, modified, restarts; + int enough, internal_pages, modified, restarts; btree = S2BT(session); cache = S2C(session)->cache; start = cache->evict + *slotp; end = WT_MIN(start + WT_EVICT_WALK_PER_FILE, cache->evict + cache->evict_slots); + enough = internal_pages = restarts = 0; walk_flags = WT_READ_CACHE | WT_READ_NO_EVICT | WT_READ_NO_GEN | WT_READ_NO_WAIT; /* * Get some more eviction candidate pages. + * + * !!! Take care terminating this loop. + * + * Don't make an extra call to __wt_tree_walk after we hit the end of a + * tree: that will leave a page pinned, which may prevent any work from + * being done. + * + * Once we hit the page limit, do one more step through the walk in + * case we are appending and only the last page in the file is live. */ - for (evict = start, pages_walked = 0, internal_pages = restarts = 0; - evict < end && pages_walked < WT_EVICT_MAX_PER_FILE && - (ret == 0 || ret == WT_NOTFOUND); + for (evict = start, pages_walked = 0; + evict < end && !enough && (ret == 0 || ret == WT_NOTFOUND); ret = __wt_tree_walk( session, &btree->evict_ref, &pages_walked, walk_flags)) { + enough = (pages_walked > WT_EVICT_MAX_PER_FILE); if (btree->evict_ref == NULL) { - /* - * Take care with terminating this loop. - * - * Don't make an extra call to __wt_tree_walk: that will - * leave a page pinned, which may prevent any work from - * being done. - */ - if (++restarts == 2) + if (++restarts == 2 || enough) break; continue; } diff --git a/src/include/extern.h b/src/include/extern.h index 23bb36623e5..5d3ee5bc8f8 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -297,7 +297,7 @@ extern int __wt_evict_server_wake(WT_SESSION_IMPL *session); extern int __wt_evict_create(WT_SESSION_IMPL *session); extern int __wt_evict_destroy(WT_SESSION_IMPL *session); extern int __wt_evict_page(WT_SESSION_IMPL *session, WT_REF *ref); -extern int __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session); +extern int __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, int *evict_resetp); extern void __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session); extern int __wt_evict_lru_page(WT_SESSION_IMPL *session, int is_server); extern int __wt_cache_wait(WT_SESSION_IMPL *session, int full); diff --git a/src/log/log_slot.c b/src/log/log_slot.c index ff61afb698c..8dcb2f9f165 100644 --- a/src/log/log_slot.c +++ b/src/log/log_slot.c @@ -203,8 +203,7 @@ retry: * churn is used to change how long we pause before closing * the slot - which leads to more consolidation and less churn. */ - if (++switch_fails % SLOT_POOL == 0 && - switch_fails != 0 && slot->slot_churn < 5) + if (++switch_fails % SLOT_POOL == 0 && slot->slot_churn < 5) ++slot->slot_churn; __wt_yield(); goto retry; |