Status: New
Owner: ----
Labels: Type-Defect Priority-Medium
New issue 183 by [email protected]: Reclaiming the space of flushed items
is needed.
http://code.google.com/p/memcached/issues/detail?id=183
What steps will reproduce the problem?
1. I found the problem in code review.
2.
3.
What is the expected output? What do you see instead?
The space of flushed items can be reused according to the following two
cases.
1. do_item_get() unlinks the flushed item when the same key is used to get
the item.
2. do_item_alloc() might evict the flushed items after fails both to find
expired items and to allocate memory from slab allocator.
If the first case does not happen, the flushed items will be evicted
according to the second case. In the second case, even if the flushed items
exist, the do_item_alloc() tries to find only expired items. So, if there
are only flushed items and no available memory in slabs, do_item_alloc()
just wastes CPU resource to find reusable/free memory. And also, since the
flushed items are evicted in the last phase of do_item_alloc(), eviction
count is incremented. But, the semantic of reusing the space of flushed
items should be reclaiming.
To solve the above problem,
the do_item_alloc() should reclaim the space of flushed items as well as
expired items in the first phase of it.
The needed code update is like followings.
item *do_item_alloc(char *key, const size_t nkey, const int flags, const
rel_time_t exptime, const int nbytes) {
. . .
for (search = tails[id];
tries > 0 && search != NULL;
tries--, search=search->prev) {
#if 1 // NEW CODE
if ((search->refcount == 0) &&
((search->exptime != 0 && search->exptime < current_time) ||
(search->time < engine->config.oldest_live &&
engine->config.oldest_live <= current_time)))
#else
if (search->refcount == 0 &&
(search->exptime != 0 && search->exptime < current_time))
#endif
{
it = search;
/* I don't want to actually free the object, just steal
* the item to avoid to grab the slab mutex twice ;-)
*/
STATS_LOCK();
stats.reclaimed++;
STATS_UNLOCK();
itemstats[id].reclaimed++;
it->refcount = 1;
slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it),
ntotal);
do_item_unlink(it);
/* Initialize the item block: */
it->slabs_clsid = 0;
it->refcount = 0;
break;
}
}
. . .
}
What version of the product are you using? On what operating system?
1.4.5 and maybe lower versions.
Please provide any additional information below.
Nothing..