Status: New
Owner: ----
Labels: Type-Defect Priority-Medium
New issue 249 by [email protected]: Problem of reclaiming valid items.
http://code.google.com/p/memcached/issues/detail?id=249
What steps will reproduce the problem?
1.just make a small-sized(with -m <num> and -M option) memcached with full
of items of exptime=0.
2. and, do send flush command with delay(86400): "flush_all 86400\r\n"
3. then, add new items into the memcached. The tail item of LRU will be
reclaimed even if the item is still valid.
What is the expected output? What do you see instead?
Expected result is "out of memory". Because there is no available memory
and no reclaimable items.
But, The tail item of LRU will be reclaimed even if the item is still valid.
It's a bug I think.
What version of the product are you using? On what operating system?
1.4.11 and below versions.
Please provide any additional information below.
The functionality of reclaiming flushed items are added memcached by fixing
issue 183.
But, the fix was not correct. It bring an another bug explained by this
issue.
The needed code fix for this bug like followings:
In the following do_item_alloc(),
the check condition for invalidated items should be changed to the new code.
Because, flush can be requested with delay option.
item *do_item_alloc(char *key, const size_t nkey, const int flags, const
rel_time_t exptime, const int nbytes) {
...
rel_time_t oldest_live = settings.oldest_live;
search = tails[id];
if (search == NULL) {
it = slabs_alloc(ntotal, id);
} else if (search->refcount == 0) {
#if 1 // new code
if ((search->time < oldest_live && oldest_live <= current_time) ||
// dead by flush
(search->exptime != 0 && search->exptime < current_time)) {
#else // old code
if ((search->time < oldest_live) || // dead by flush
(search->exptime != 0 && search->exptime < current_time)) {
#endif
STATS_LOCK();
stats.reclaimed++;
STATS_UNLOCK();
itemstats[id].reclaimed++;
if ((search->it_flags & ITEM_FETCHED) == 0) {
STATS_LOCK();
stats.expired_unfetched++;
STATS_UNLOCK();
itemstats[id].expired_unfetched++;
}
it = search;
it->refcount = 1;
slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it),
ntotal);
do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0));
/* Initialize the item block: */
it->slabs_clsid = 0;
it->refcount = 0;
}
}
...
}