Hi,

after adding new nodes in our memcached in production, where we don't
use consistent hashing, we flushed our nodes one by one (with a large
delay between each to avoid impact on the DB). Unfortunately, although
we notice the corresponding increase of traffic we didn't see any
impact on the increase of memory usage and number of pages.

I had a look at the source code and I understand why. The oldest_live
variable is checked only when doing a get, which wasn't the case
anymore for the values we wanted to remove as the distribution had
changed and those values weren't read

Therefore, I suggest the following change in items.c which not only
replace expired items when doing a set but also flushed ones:

diff --git a/items.c b/items.c
index 3e7f8c4..5eb3a52 100644
--- a/items.c
+++ b/items.c
@@ -103,7 +103,7 @@ item *do_item_alloc(char *key, const size_t nkey,
const int flags, const rel_tim
          tries > 0 && search != NULL;
          tries--, search=search->prev) {
         if (search->refcount == 0 &&
-            (search->exptime != 0 && search->exptime < current_time))
{
+            ((search->exptime != 0 && search->exptime < current_time)
|| (search->time <= settings.oldest_live))) {
             it = search;
             /* I don't want to actually free the object, just steal
              * the item to avoid to grab the slab mutex twice ;-)

Regards,
Colin

Reply via email to