summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2013-10-24 16:57:11 -0400
committerKeith Bostic <keith@wiredtiger.com>2013-10-24 16:57:11 -0400
commitfd990b2101b3e3fff260e78de9be34875e092657 (patch)
tree3a6b39ca584a966c33e39aa361d968fb93ad4b5e
parent794365cb306d7cd86d73ae9b2d922193dfbdb2ce (diff)
downloadmongo-fd990b2101b3e3fff260e78de9be34875e092657.tar.gz
Don't keep accumulating pages once we've hit max_entries, that's
supposed to limit the pages we acquire for the LRU queue. Replace the file counting mechanism for restarting at the same spot in the dhandle list with a reference to a field of the dhandle structure.
-rw-r--r--src/btree/bt_evict.c58
-rw-r--r--src/include/cache.h3
2 files changed, 39 insertions, 22 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index 8c2eff024a5..fab1b373944 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -700,44 +700,55 @@ __evict_walk(WT_SESSION_IMPL *session, u_int *entriesp, int clean)
WT_CONNECTION_IMPL *conn;
WT_DATA_HANDLE *dhandle;
WT_DECL_RET;
- u_int file_count, i, max_entries, retries;
+ u_int slot, max_entries, retries;
conn = S2C(session);
cache = S2C(session)->cache;
retries = 0;
/*
- * NOTE: we don't hold the schema lock, so we have to take care
- * that the handles we see are open and valid.
+ * Set the starting slot in the queue and the maximum pages added
+ * per walk.
*/
- i = cache->evict_entries;
- max_entries = i + WT_EVICT_WALK_INCR;
+ slot = cache->evict_entries;
+ max_entries = slot + WT_EVICT_WALK_INCR;
+
/*
* Lock the dhandle list so sweeping cannot change the pointers out
* from under us.
+ *
+ * NOTE: we don't hold the schema lock, so we have to take care
+ * that the handles we see are open and valid.
*/
__wt_spin_lock(session, &conn->dhandle_lock);
-retry: file_count = 0;
- SLIST_FOREACH(dhandle, &conn->dhlh, l) {
+
+retry: SLIST_FOREACH(dhandle, &conn->dhlh, l) {
+ /* Ignore non-file handles, or handles that aren't open. */
if (!WT_PREFIX_MATCH(dhandle->name, "file:") ||
!F_ISSET(dhandle, WT_DHANDLE_OPEN))
continue;
- if (file_count++ < cache->evict_file_next)
+
+ /*
+ * Each time we reenter this function, start at the next handle
+ * on the list. We use the address of the handle's name as the
+ * handle's unique identifier, that should be unique, and is
+ * unlikely to cause a false positive if freed and reallocated.
+ */
+ if (cache->evict_file_next != NULL &&
+ cache->evict_file_next != dhandle->name)
continue;
- btree = dhandle->handle;
+ cache->evict_file_next = NULL;
/*
- * Skip files that aren't open or don't have a root page.
- *
- * Also skip files marked as cache-resident, and files
- * potentially involved in a bulk load. The real problem is
+ * Skip files without a root page, marked as cache-resident and
+ * files potentially involved in a bulk-load. The problem is
* eviction doesn't want to be walking the file as it converts
* to a bulk-loaded object, and empty trees aren't worth trying
* to evict, anyway.
*/
+ btree = dhandle->handle;
if (btree->root_page == NULL ||
- F_ISSET(btree, WT_BTREE_NO_EVICTION) ||
- btree->bulk_load_ok)
+ F_ISSET(btree, WT_BTREE_NO_EVICTION) || btree->bulk_load_ok)
continue;
__wt_spin_lock(session, &cache->evict_walk_lock);
@@ -748,21 +759,26 @@ retry: file_count = 0;
*/
if (!F_ISSET(btree, WT_BTREE_NO_EVICTION))
WT_WITH_BTREE(session, btree,
- ret = __evict_walk_file(session, &i, clean));
+ ret = __evict_walk_file(session, &slot, clean));
__wt_spin_unlock(session, &cache->evict_walk_lock);
- if (ret != 0 || i == max_entries)
+ if (ret != 0 || slot >= max_entries)
break;
}
- cache->evict_file_next = (dhandle == NULL) ? 0 : file_count;
- /* Walk the files a few times if we don't find enough pages. */
- if (ret == 0 && i < cache->evict_slots && retries++ < 10)
+ /* Walk the list of files a few times if we don't find enough pages. */
+ if (ret == 0 && slot < max_entries && ++retries < 10)
goto retry;
+
+ /* Remember the file we should visit first, next loop. */
+ if (dhandle != NULL)
+ dhandle = SLIST_NEXT(dhandle, l);
+ cache->evict_file_next = dhandle == NULL ? NULL : dhandle->name;
+
__wt_spin_unlock(session, &conn->dhandle_lock);
- *entriesp = i;
+ *entriesp = slot;
return (ret);
}
diff --git a/src/include/cache.h b/src/include/cache.h
index ee874af51df..e4ba18cc31f 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -70,7 +70,8 @@ struct __wt_cache {
uint32_t evict_entries; /* LRU entries in the queue */
volatile uint32_t evict_max; /* LRU maximum eviction slot used */
uint32_t evict_slots; /* LRU list eviction slots */
- u_int evict_file_next; /* LRU: next file to search */
+ const void
+ *evict_file_next; /* LRU next file to search */
uint32_t force_entries; /* Forced eviction page count */
/*