summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-02-24 14:48:18 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-02-24 14:48:18 +1100
commit92b95f55d99a88d94aa5c14da6e8bd4f13408e24 (patch)
tree1f7e3bcf449f8d676baf21c4d0dd93c605e68f3d
parentce89b608835561b11ce4e525a5ebdad86558f115 (diff)
parent303b826d41cf42b952517e4cec2a1003fd860e60 (diff)
downloadmongo-92b95f55d99a88d94aa5c14da6e8bd4f13408e24.tar.gz
Merge branch 'develop' into statistics-sources-handle-overwrite
-rw-r--r--src/btree/bt_compact.c7
-rw-r--r--src/btree/bt_page.c17
-rw-r--r--src/btree/bt_sync.c7
-rw-r--r--src/evict/evict_file.c11
-rw-r--r--src/evict/evict_lru.c38
-rw-r--r--src/include/extern.h2
-rw-r--r--src/log/log_slot.c3
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;