Add fails after delete
Brad Fitzpatrick
brad@danga.com
Thu, 15 Jul 2004 12:48:21 -0700 (PDT)
On Thu, 15 Jul 2004, Michael Alan Dorman wrote:
> I think this is a bug.
>
> If you set a key, then delete it, then try to add it, it seems to me
> it should add successfully. However, as the attached script seems to
> demonstrate, the add fails.
This may well be a bug. It's time-dependent, too. If you put a
"sleep 1" between your delete and get, it works.
Tracing it:
The perl delete without an expiration time sends nothing, so memcached
parses it as expiration time 0, and transforms it via:
exptime = realtime(exptime);
Which keeps it at 0 (meaning immediately).
Then its refcount is increased and marked to be deleted:
it->refcount++;
/* use its expiration time as its deletion time now */
it->exptime = exptime;
it->it_flags |= ITEM_DELETED;
todelete[delcurr++] = it;
if (delcurr >= deltotal) {
deltotal *= 2;
todelete = realloc(todelete, sizeof(item *)*deltotal);
}
out_string(c, "DELETED");
Next, the get comes in. (and it's odd here because time matters)
while(sscanf(start, " %250s%n", key, &next) >= 1) {
start+=next;
stats.get_cmds++;
it = assoc_find(key);
if (it && (it->it_flags & ITEM_DELETED)) {
it = 0;
}
It should mark it as not found, which it does. But the item still exists.
Ah, the delete_handler only runs every 5 seconds. So there's the time
mystery.
Then the add comes in:
if ((strncmp(command, "add ", 4) == 0 && (comm = NREAD_ADD)) ||
And later, after data is read:
old_it = assoc_find(ITEM_key(it));
if (old_it && old_it->exptime && old_it->exptime <= now) {
item_unlink(old_it);
old_it = 0;
}
if (old_it && comm==NREAD_ADD) {
item_update(old_it);
out_string(c, "NOT_STORED");
break;
}
Because exptime == 0, it's not unlinked from the LRU.
Avva: I remember why we don't unlink it from the LRU in the time-delayed
delete case (the old default), but when the provided delay value is 0, why
don't we just immediately unlink it?
- Brad
>
> I haven't looked particulary hard at this---I only ran across it while
> constructing a set of test cases for some libraries and being lazy at
> the same time---re-running the same adds I had used to construct the
> key I had just deleted.
>
> Mike
> --
> I'm selling my soul again, I'm gaining the world -- David Sylvian
>