flush_all functionality at given time

Elizabeth Mattijsen liz at dijkmat.nl
Wed Jul 6 11:17:12 PDT 2005

Because I needed a way to flush all memcached backend servers, but 
not at exactly the same time (to reduce load peaks), I've added some 
simple functionality to the memcached protocol in the "flush_all" 
command that allows you to specify a time at which the flush will 
actually occur (instead of always at the moment the "flush_all" 
command is received).

So, apart from just "flush_all", you can now also specify an 
expiration for the flush to occur.

flush_all\r\n		// flushes now
flush_all 10\r\n		// flushes in 10 seconds
flush_all 1120673174\r\n	// flushes at Wed Jul  6 18:06:14 2005 GMT

Below you will find the patch to add this functionality.  I've also 
added this as an attachment in case my mailer messes up the 
whitespace so that the patch cannot be applied (it has been known to 
do that in the past).

Hope this will make it to the standard distribution of memcached at 
some point soon.

On a related note: I noticed that Cache::Memcached module does not 
contain support for "flush_all" yet.  Would it be a good idea if I 
supplied patches for adding that functionality to Cache::Memcached as 

Elizabeth Mattijsen
--- memcached.c.1.1.12	2005-04-05 02:10:26.000000000 +0200
+++ memcached.c	2005-07-06 20:01:02.000000000 +0200
@@ -619,8 +619,8 @@
              if (it && (it->it_flags & ITEM_DELETED)) {
                  it = 0;
-            if (settings.oldest_live && it &&
-                it->time <= settings.oldest_live) {
+            if (settings.oldest_live && settings.oldest_live <= now &&
+                it && it->time <= settings.oldest_live) {
                  it = 0;
@@ -707,8 +707,23 @@

-    if (strcmp(command, "flush_all") == 0) {
-        settings.oldest_live = time(0);
+    if (strncmp(command, "flush_all", 9) == 0) {
+        time_t exptime = 0;
+        int res;
+        if (strcmp(command, "flush_all") == 0) {
+            settings.oldest_live = time(0);
+            out_string(c, "OK");
+            return;
+        }
+        res = sscanf(command, "%*s %ld", &exptime);
+        if (res != 1) {
+            out_string(c, "ERROR");
+            return;
+        }
+        settings.oldest_live = realtime(exptime);
          out_string(c, "OK");
--- doc/protocol.txt.1.1.12	2004-04-26 23:26:48.000000000 +0200
+++ doc/protocol.txt	2005-07-06 20:09:24.000000000 +0200
@@ -359,16 +359,17 @@
  Other commands

-"flush_all" is a command with no arguments. It always succeeds,
-and the server sends "OK\r\n" in response. Its effect is to immediately
-invalidate all existing items: none of them will be returned in
-response to a retrieval command (unless it's stored again under the
-same key *after* flush_all has been executed). flush_all doesn't
+"flush_all" is a command with an optional numeric argument. It always
+succeeds, and the server sends "OK\r\n" in response. Its effect is to
+invalidate all existing items immediately (by default) or after the
+expiration specified.  After invalidation none of the items will be returned
+in response to a retrieval command (unless it's stored again under the
+same key *after* flush_all has invalidated the items). flush_all doesn't
  actually free all the memory taken up by existing items; that will
  happen gradually as new items are stored. The most precise definition
  of what flush_all does is the following: it causes all items whose
-update time is earlier than the time at which flush_all was executed
-to be ignored for retrieval purposes.
+update time is earlier than the time at which flush_all was set to be
+executed to be ignored for retrieval purposes.

  "version" is a command with no arguments:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: memcached.patch
Type: application/octet-stream
Size: 2614 bytes
Desc: not available
Url : http://lists.danga.com/pipermail/memcached/attachments/20050706/c706f12b/memcached.obj

More information about the memcached mailing list