diff options
author | Keith Bostic <keith@wiredtiger.com> | 2013-10-24 16:57:11 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2013-10-24 16:57:11 -0400 |
commit | fd990b2101b3e3fff260e78de9be34875e092657 (patch) | |
tree | 3a6b39ca584a966c33e39aa361d968fb93ad4b5e | |
parent | 794365cb306d7cd86d73ae9b2d922193dfbdb2ce (diff) | |
download | mongo-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.c | 58 | ||||
-rw-r--r-- | src/include/cache.h | 3 |
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 */ /* |