]> git.saurik.com Git - redis.git/commitdiff
Updated to unstable
authorantirez <antirez@gmail.com>
Tue, 14 Jun 2011 16:06:39 +0000 (18:06 +0200)
committerantirez <antirez@gmail.com>
Tue, 14 Jun 2011 16:06:39 +0000 (18:06 +0200)
1  2 
redis.conf
src/Makefile
src/config.c
src/redis.c
src/redis.h
tests/test_helper.tcl

diff --combined redis.conf
index f962b970407acf9696901ec99e0c076e80b520fb,87d34eef02cf580930d913e2de4e38722092a2c5..6999dae3476cff578f8bed2004575ecfe73d037d
@@@ -292,13 -292,26 +292,33 @@@ appendfsync everyse
  # "no" that is the safest pick from the point of view of durability.
  no-appendfsync-on-rewrite no
  
+ # Automatic rewrite of the append only file.
+ # Redis is able to automatically rewrite the log file implicitly calling
+ # BGREWRITEAOF when the AOF log size will growth by the specified percentage.
+ # 
+ # This is how it works: Redis remembers the size of the AOF file after the
+ # latest rewrite (or if no rewrite happened since the restart, the size of
+ # the AOF at startup is used).
+ #
+ # This base size is compared to the current size. If the current size is
+ # bigger than the specified percentage, the rewrite is triggered. Also
+ # you need to specify a minimal size for the AOF file to be rewritten, this
+ # is useful to avoid rewriting the AOF file even if the percentage increase
+ # is reached but it is still pretty small.
+ #
+ # Specify a precentage of zero in order to disable the automatic AOF
+ # rewrite feature.
+ auto-aof-rewrite-percentage 100
+ auto-aof-rewrite-min-size 64mb
 +################################ LUA SCRIPTING  ###############################
 +
 +# Max execution time of a Lua script in milliseconds.
 +# This prevents that a programming error generating an infinite loop will block
 +# your server forever. Set it to 0 or a negative value for unlimited execution.
 +lua-time-limit 60000
 +
  #################################### DISK STORE ###############################
  
  # When disk store is active Redis works as an on-disk database, where memory
diff --combined src/Makefile
index ee2bf5e34c4a46b5a7eb12abb15c145d407713d3,8d903c9091a87d49410ee716d052dccf85baf58e..e23ed038c0dc2042b171e7fbc2b56be728754c24
@@@ -46,7 -46,12 +46,12 @@@ BINCOLOR="\033[37;1m
  MAKECOLOR="\033[32;1m"
  ENDCOLOR="\033[0m"
  
 -OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o dscache.o pubsub.o multi.o debug.o sort.o intset.o syncio.o diskstore.o cluster.o crc16.o endian.o
+ ifndef V
+ QUIET_CC = @printf '    %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR);
+ QUIET_LINK = @printf '    %b %b\n' $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR);
+ endif
 +OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o dscache.o pubsub.o multi.o debug.o sort.o intset.o syncio.o diskstore.o cluster.o crc16.o endian.o scripting.o
  BENCHOBJ = ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
  CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o release.o
  CHECKDUMPOBJ = redis-check-dump.o lzf_c.o lzf_d.o
@@@ -132,45 -137,35 +137,37 @@@ zipmap.o: zipmap.c zmalloc.
  zmalloc.o: zmalloc.c config.h
  
  dependencies:
-       @echo $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)hiredis$(ENDCOLOR)
+       @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)hiredis$(ENDCOLOR)
        @cd ../deps/hiredis && $(MAKE) static ARCH="$(ARCH)"
-       @echo $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)linenoise$(ENDCOLOR)
+       @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)linenoise$(ENDCOLOR)
        @cd ../deps/linenoise && $(MAKE) ARCH="$(ARCH)"
 +      @echo $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)Lua ansi$(ENDCOLOR)
 +      @cd ../deps/lua && $(MAKE) ARCH="$(ARCH)" ansi
  
  redis-server: $(OBJ)
-       @$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ) ../deps/lua/src/liblua.a
-       @echo $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$(@)$(ENDCOLOR)
 -      $(QUIET_CC)$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
++      $(QUIET_CC)$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ) ../deps/lua/src/liblua.a
  
  redis-benchmark: dependencies $(BENCHOBJ)
        @cd ../deps/hiredis && $(MAKE) static
-       @$(CC) -o $(BENCHPRGNAME) $(CCOPT) $(DEBUG) $(BENCHOBJ) ../deps/hiredis/libhiredis.a
-       @echo $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$(@)$(ENDCOLOR)
+       $(QUIET_LINK)$(CC) -o $(BENCHPRGNAME) $(CCOPT) $(DEBUG) $(BENCHOBJ) ../deps/hiredis/libhiredis.a
  
  redis-benchmark.o:
-       @$(CC) -c $(CFLAGS) -I../deps/hiredis $(DEBUG) $(COMPILE_TIME) $<
-       @echo $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$(<)$(ENDCOLOR)
+       $(QUIET_CC)$(CC) -c $(CFLAGS) -I../deps/hiredis $(DEBUG) $(COMPILE_TIME) $<
  
  redis-cli: dependencies $(CLIOBJ)
-       @$(CC) -o $(CLIPRGNAME) $(CCOPT) $(DEBUG) $(CLIOBJ) ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
-       @echo $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$(@)$(ENDCOLOR)
+       $(QUIET_LINK)$(CC) -o $(CLIPRGNAME) $(CCOPT) $(DEBUG) $(CLIOBJ) ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
  
  redis-cli.o:
-       @$(CC) -c $(CFLAGS) -I../deps/hiredis -I../deps/linenoise $(DEBUG) $(COMPILE_TIME) $<
-       @echo $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$(<)$(ENDCOLOR)
+       $(QUIET_CC)$(CC) -c $(CFLAGS) -I../deps/hiredis -I../deps/linenoise $(DEBUG) $(COMPILE_TIME) $<
  
  redis-check-dump: $(CHECKDUMPOBJ)
-       @$(CC) -o $(CHECKDUMPPRGNAME) $(CCOPT) $(DEBUG) $(CHECKDUMPOBJ)
-       @echo $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$(@)$(ENDCOLOR)
+       $(QUIET_LINK)$(CC) -o $(CHECKDUMPPRGNAME) $(CCOPT) $(DEBUG) $(CHECKDUMPOBJ)
  
  redis-check-aof: $(CHECKAOFOBJ)
-       @$(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ)
-       @echo $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$(@)$(ENDCOLOR)
+       $(QUIET_LINK)$(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ)
  
  .c.o:
-       @$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) -I../deps/lua/src $<
-       @echo $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$(<)$(ENDCOLOR)
 -      $(QUIET_CC)$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $<
++      $(QUIET_CC)$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) -I../deps/lua/src $<
  
  clean:
        rm -rf $(PRGNAME) $(BENCHPRGNAME) $(CLIPRGNAME) $(CHECKDUMPPRGNAME) $(CHECKAOFPRGNAME) *.o *.gcda *.gcno *.gcov
diff --combined src/config.c
index d4608559d28a37874feae30d311bec05e466269d,9d30d9859735e9617fc06658421aa665f33fbce4..4f4514c8956c00b9b903879a29e87872b844c858
@@@ -231,6 -231,18 +231,18 @@@ void loadServerConfig(char *filename) 
                  err = "argument must be 'no', 'always' or 'everysec'";
                  goto loaderr;
              }
+         } else if (!strcasecmp(argv[0],"auto-aof-rewrite-percentage") &&
+                    argc == 2)
+         {
+             server.auto_aofrewrite_perc = atoi(argv[1]);
+             if (server.auto_aofrewrite_perc < 0) {
+                 err = "Invalid negative percentage for AOF auto rewrite";
+                 goto loaderr;
+             }
+         } else if (!strcasecmp(argv[0],"auto-aof-rewrite-min-size") &&
+                    argc == 2)
+         {
+             server.auto_aofrewrite_min_size = memtoll(argv[1],NULL);
          } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
              server.requirepass = zstrdup(argv[1]);
          } else if (!strcasecmp(argv[0],"pidfile") && argc == 2) {
          } else if (!strcasecmp(argv[0],"cluster-config-file") && argc == 2) {
              zfree(server.cluster.configfile);
              server.cluster.configfile = zstrdup(argv[1]);
 +        } else if (!strcasecmp(argv[0],"lua-time-limit") && argc == 2) {
 +            server.lua_time_limit = strtoll(argv[1],NULL,10);
          } else {
              err = "Bad directive or wrong number of arguments"; goto loaderr;
          }
@@@ -397,6 -407,12 +409,12 @@@ void configSetCommand(redisClient *c) 
                  }
              }
          }
+     } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-percentage")) {
+         if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
+         server.auto_aofrewrite_perc = ll;
+     } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-min-size")) {
+         if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
+         server.auto_aofrewrite_min_size = ll;
      } else if (!strcasecmp(c->argv[2]->ptr,"save")) {
          int vlen, j;
          sds *v = sdssplitlen(o->ptr,sdslen(o->ptr)," ",1,&vlen);
      } else if (!strcasecmp(c->argv[2]->ptr,"zset-max-ziplist-value")) {
          if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
          server.zset_max_ziplist_value = ll;
 +    } else if (!strcasecmp(c->argv[2]->ptr,"lua-time-limit")) {
 +        if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
 +        server.lua_time_limit = ll;
      } else {
          addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
              (char*)c->argv[2]->ptr);
@@@ -586,6 -599,16 +604,16 @@@ void configGetCommand(redisClient *c) 
          sdsfree(buf);
          matches++;
      }
+     if (stringmatch(pattern,"auto-aof-rewrite-percentage",0)) {
+         addReplyBulkCString(c,"auto-aof-rewrite-percentage");
+         addReplyBulkLongLong(c,server.auto_aofrewrite_perc);
+         matches++;
+     }
+     if (stringmatch(pattern,"auto-aof-rewrite-min-size",0)) {
+         addReplyBulkCString(c,"auto-aof-rewrite-min-size");
+         addReplyBulkLongLong(c,server.auto_aofrewrite_min_size);
+         matches++;
+     }
      if (stringmatch(pattern,"slave-serve-stale-data",0)) {
          addReplyBulkCString(c,"slave-serve-stale-data");
          addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no");
          addReplyBulkLongLong(c,server.zset_max_ziplist_value);
          matches++;
      }
 +    if (stringmatch(pattern,"lua-time-limit",0)) {
 +        addReplyBulkCString(c,"lua-time-limit");
 +        addReplyBulkLongLong(c,server.lua_time_limit);
 +        matches++;
 +    }
      setDeferredMultiBulkLength(c,replylen,matches*2);
  }
  
diff --combined src/redis.c
index d5470ff37f9dfd38aa77699659b69d88297c27e1,e7351b6ef5381001b8b78dc221fad40a85a12fc0..ee5e1a21ed6a4f540eb80972fd79a00aaf873f57
@@@ -116,9 -116,9 +116,9 @@@ struct redisCommand redisCommandTable[
      {"sdiff",sdiffCommand,-2,REDIS_CMD_DENYOOM,NULL,1,-1,1,0,0},
      {"sdiffstore",sdiffstoreCommand,-3,REDIS_CMD_DENYOOM,NULL,2,-1,1,0,0},
      {"smembers",sinterCommand,2,0,NULL,1,1,1,0,0},
-     {"zadd",zaddCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1,0,0},
+     {"zadd",zaddCommand,-4,REDIS_CMD_DENYOOM,NULL,1,1,1,0,0},
      {"zincrby",zincrbyCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1,0,0},
-     {"zrem",zremCommand,3,0,NULL,1,1,1,0,0},
+     {"zrem",zremCommand,-3,0,NULL,1,1,1,0,0},
      {"zremrangebyscore",zremrangebyscoreCommand,4,0,NULL,1,1,1,0,0},
      {"zremrangebyrank",zremrangebyrankCommand,4,0,NULL,1,1,1,0,0},
      {"zunionstore",zunionstoreCommand,-4,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0},
      {"migrate",migrateCommand,6,0,NULL,0,0,0,0,0},
      {"dump",dumpCommand,2,0,NULL,0,0,0,0,0},
      {"object",objectCommand,-2,0,NULL,0,0,0,0,0},
 -    {"client",clientCommand,-2,0,NULL,0,0,0,0,0}
 +    {"client",clientCommand,-2,0,NULL,0,0,0,0,0},
 +    {"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0},
 +    {"evalsha",evalShaCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}
  };
  
  /*============================ Utility functions ============================ */
@@@ -635,6 -633,14 +635,14 @@@ int serverCron(struct aeEventLoop *even
      if ((server.maxidletime && !(loops % 100)) || server.bpop_blocked_clients)
          closeTimedoutClients();
  
+     /* Start a scheduled AOF rewrite if this was requested by the user while
+      * a BGSAVE was in progress. */
+     if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1 &&
+         server.aofrewrite_scheduled)
+     {
+         rewriteAppendOnlyFileBackground();
+     }
      /* Check if a background saving or AOF rewrite in progress terminated. */
      if (server.bgsavechildpid != -1 || server.bgrewritechildpid != -1) {
          int statloc;
              }
          }
      } else if (!server.ds_enabled) {
-         /* If there is not a background saving in progress check if
-          * we have to save now */
           time_t now = time(NULL);
+         /* If there is not a background saving/rewrite in progress check if
+          * we have to save/rewrite now */
           for (j = 0; j < server.saveparamslen; j++) {
              struct saveparam *sp = server.saveparams+j;
  
                  break;
              }
           }
+          /* Trigger an AOF rewrite if needed */
+          if (server.bgsavechildpid == -1 &&
+              server.bgrewritechildpid == -1 &&
+              server.auto_aofrewrite_perc &&
+              server.appendonly_current_size > server.auto_aofrewrite_min_size)
+          {
+             int base = server.auto_aofrewrite_base_size ?
+                             server.auto_aofrewrite_base_size : 1;
+             long long growth = (server.appendonly_current_size*100/base) - 100;
+             if (growth >= server.auto_aofrewrite_perc) {
+                 redisLog(REDIS_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
+                 rewriteAppendOnlyFileBackground();
+             }
+          }
      }
  
      /* Expire a few keys per cycle, only if this is a master.
@@@ -782,8 -804,6 +806,8 @@@ void createSharedObjects(void) 
          "-ERR source and destination objects are the same\r\n"));
      shared.outofrangeerr = createObject(REDIS_STRING,sdsnew(
          "-ERR index out of range\r\n"));
 +    shared.noscripterr = createObject(REDIS_STRING,sdsnew(
 +        "-NOSCRIPT No matching script. Please use EVAL.\r\n"));
      shared.loadingerr = createObject(REDIS_STRING,sdsnew(
          "-LOADING Redis is loading the dataset in memory\r\n"));
      shared.space = createObject(REDIS_STRING,sdsnew(" "));
@@@ -832,6 -852,10 +856,10 @@@ void initServerConfig() 
      server.appendonly = 0;
      server.appendfsync = APPENDFSYNC_EVERYSEC;
      server.no_appendfsync_on_rewrite = 0;
+     server.auto_aofrewrite_perc = REDIS_AUTO_AOFREWRITE_PERC;
+     server.auto_aofrewrite_min_size = REDIS_AUTO_AOFREWRITE_MIN_SIZE;
+     server.auto_aofrewrite_base_size = 0;
+     server.aofrewrite_scheduled = 0;
      server.lastfsync = time(NULL);
      server.appendfd = -1;
      server.appendseldb = -1; /* Make sure the first time will not match */
      server.cache_flush_delay = 0;
      server.cluster_enabled = 0;
      server.cluster.configfile = zstrdup("nodes.conf");
 +    server.lua_time_limit = REDIS_LUA_TIME_LIMIT;
  
      updateLRUClock();
      resetServerSaveParams();
      server.masterport = 6379;
      server.master = NULL;
      server.replstate = REDIS_REPL_NONE;
+     server.repl_syncio_timeout = REDIS_REPL_SYNCIO_TIMEOUT;
      server.repl_serve_stale_data = 1;
  
      /* Double constants initialization */
@@@ -968,6 -992,7 +997,7 @@@ void initServer() 
      server.stat_keyspace_misses = 0;
      server.stat_keyspace_hits = 0;
      server.stat_peak_memory = 0;
+     server.stat_fork_time = 0;
      server.unixtime = time(NULL);
      aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL);
      if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE,
  
      if (server.ds_enabled) dsInit();
      if (server.cluster_enabled) clusterInit();
 +    scriptingInit();
      srand(time(NULL)^getpid());
  }
  
@@@ -1324,7 -1348,6 +1354,7 @@@ sds genRedisInfoString(char *section) 
              "used_memory_rss:%zu\r\n"
              "used_memory_peak:%zu\r\n"
              "used_memory_peak_human:%s\r\n"
 +            "used_memory_lua:%lld\r\n"
              "mem_fragmentation_ratio:%.2f\r\n"
              "mem_allocator:%s\r\n",
              zmalloc_used_memory(),
              zmalloc_get_rss(),
              server.stat_peak_memory,
              peak_hmem,
 +            ((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL,
              zmalloc_get_fragmentation_ratio(),
              REDIS_MALLOC
              );
              server.lastsave,
              server.bgrewritechildpid != -1);
  
+         if (server.appendonly) {
+             info = sdscatprintf(info,
+                 "aof_current_size:%lld\r\n"
+                 "aof_base_size:%lld\r\n"
+                 "aof_pending_rewrite:%d\r\n",
+                 (long long) server.appendonly_current_size,
+                 (long long) server.auto_aofrewrite_base_size,
+                 server.aofrewrite_scheduled);
+         }
          if (server.loading) {
              double perc;
              time_t eta, elapsed;
              "keyspace_hits:%lld\r\n"
              "keyspace_misses:%lld\r\n"
              "pubsub_channels:%ld\r\n"
-             "pubsub_patterns:%u\r\n",
+             "pubsub_patterns:%u\r\n"
+             "latest_fork_usec:%lld\r\n",
              server.stat_numconnections,
              server.stat_numcommands,
              server.stat_expiredkeys,
              server.stat_keyspace_hits,
              server.stat_keyspace_misses,
              dictSize(server.pubsub_channels),
-             listLength(server.pubsub_patterns));
+             listLength(server.pubsub_patterns),
+             server.stat_fork_time);
      }
  
      /* Replication */
diff --combined src/redis.h
index 923d6f75db5395c7b7120ca63eea5fb43a70255d,ce62d226be46f029e4d20a0a51a39acb506646fa..fec7355b5d02bea07a3087d1be4a04b0cd8e9b21
@@@ -19,7 -19,6 +19,7 @@@
  #include <pthread.h>
  #include <syslog.h>
  #include <netinet/in.h>
 +#include <lua.h>
  
  #include "ae.h"     /* Event driven programming library */
  #include "sds.h"    /* Dynamic safe strings */
@@@ -42,7 -41,6 +42,6 @@@
  #define REDIS_MAXIDLETIME       (60*5)  /* default client timeout */
  #define REDIS_IOBUF_LEN         1024
  #define REDIS_LOADBUF_LEN       1024
- #define REDIS_STATIC_ARGS       8
  #define REDIS_DEFAULT_DBNUM     16
  #define REDIS_CONFIGLINE_MAX    1024
  #define REDIS_MAX_SYNC_TIME     60      /* Slave can't take more to sync */
@@@ -52,6 -50,8 +51,8 @@@
  #define REDIS_SHARED_INTEGERS 10000
  #define REDIS_REPLY_CHUNK_BYTES (5*1500) /* 5 TCP packets with default MTU */
  #define REDIS_MAX_LOGMSG_LEN    1024 /* Default maximum length of syslog messages */
+ #define REDIS_AUTO_AOFREWRITE_PERC  100
+ #define REDIS_AUTO_AOFREWRITE_MIN_SIZE (1024*1024)
  
  /* Hash table parameters */
  #define REDIS_HT_MINFILL        10      /* Minimal hash table fill 10% */
  #define REDIS_CLOSE_AFTER_REPLY 128 /* Close after writing entire reply. */
  #define REDIS_UNBLOCKED 256 /* This client was unblocked and is stored in
                                 server.unblocked_clients */
 +#define REDIS_LUA_CLIENT 512 /* This is a non connected client used by Lua */
  
  /* Client request types */
  #define REDIS_REQ_INLINE 1
  #define REDIS_REQ_MULTIBULK 2
  
  /* Slave replication state - slave side */
- #define REDIS_REPL_NONE 0   /* No active replication */
- #define REDIS_REPL_CONNECT 1    /* Must connect to master */
- #define REDIS_REPL_TRANSFER 2    /* Receiving .rdb from master */
- #define REDIS_REPL_CONNECTED 3  /* Connected to master */
+ #define REDIS_REPL_NONE 0 /* No active replication */
+ #define REDIS_REPL_CONNECT 1 /* Must connect to master */
+ #define REDIS_REPL_CONNECTING 2 /* Connecting to master */
+ #define REDIS_REPL_TRANSFER 3 /* Receiving .rdb from master */
+ #define REDIS_REPL_CONNECTED 4 /* Connected to master */
+ /* Synchronous read timeout - slave side */
+ #define REDIS_REPL_SYNCIO_TIMEOUT 5
  
  /* Slave replication state - from the point of view of master
   * Note that in SEND_BULK and ONLINE state the slave receives new updates
  #define REDIS_BGSAVE_THREAD_DONE_OK 2
  #define REDIS_BGSAVE_THREAD_DONE_ERR 3
  
 +/* Scripting */
 +#define REDIS_LUA_TIME_LIMIT 60000 /* milliseconds */
 +
  /* We can print the stacktrace, so our assert is defined this way: */
  #define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
  #define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
@@@ -365,7 -365,7 +370,7 @@@ struct sharedObjectsStruct 
      robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *cnegone, *pong, *space,
      *colon, *nullbulk, *nullmultibulk, *queued,
      *emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
 -    *outofrangeerr, *loadingerr, *plus,
 +    *outofrangeerr, *noscripterr, *loadingerr, *plus,
      *select0, *select1, *select2, *select3, *select4,
      *select5, *select6, *select7, *select8, *select9,
      *messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3,
@@@ -548,6 -548,7 +553,7 @@@ struct redisServer 
      long long stat_keyspace_hits;   /* number of successful lookups of keys */
      long long stat_keyspace_misses; /* number of failed lookups of keys */
      size_t stat_peak_memory;        /* max used memory record */
+     long long stat_fork_time;       /* time needed to perform latets fork() */
      /* Configuration */
      int verbosity;
      int maxidletime;
      int appendonly;
      int appendfsync;
      int no_appendfsync_on_rewrite;
+     int auto_aofrewrite_perc;       /* Rewrite AOF if % growth is > M and... */
+     off_t auto_aofrewrite_min_size; /* the AOF file is at least N bytes. */
+     off_t auto_aofrewrite_base_size;/* AOF size on latest startup or rewrite. */
+     off_t appendonly_current_size;  /* AOF current size. */
+     int aofrewrite_scheduled;       /* Rewrite once BGSAVE terminates. */
      int shutdown_asap;
      int activerehashing;
      char *requirepass;
      char *masterhost;
      int masterport;
      redisClient *master;    /* client that is master for this slave */
+     int repl_syncio_timeout; /* timeout for synchronous I/O calls */
      int replstate;          /* replication status if the instance is a slave */
      off_t repl_transfer_left;  /* bytes left reading .rdb  */
      int repl_transfer_s;    /* slave -> master SYNC socket */
      /* Cluster */
      int cluster_enabled;
      clusterState cluster;
 +    /* Scripting */
 +    lua_State *lua;
 +    redisClient *lua_client;
 +    long long lua_time_limit;
 +    long long lua_time_start;
  };
  
  typedef struct pubsubPattern {
@@@ -898,7 -900,6 +910,6 @@@ int fwriteBulkCount(FILE *fp, char pref
  /* Replication */
  void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc);
  void replicationFeedMonitors(list *monitors, int dictid, robj **argv, int argc);
- int syncWithMaster(void);
  void updateSlavesWaitingBgsave(int bgsaveerr);
  void replicationCron(void);
  
@@@ -963,7 -964,6 +974,7 @@@ struct redisCommand *lookupCommandByCSt
  void call(redisClient *c, struct redisCommand *cmd);
  int prepareForShutdown();
  void redisLog(int level, const char *fmt, ...);
 +void redisLogRaw(int level, const char *msg);
  void usage();
  void updateDictResizePolicy(void);
  int htNeedsResize(dict *dict);
@@@ -1086,9 -1086,6 +1097,9 @@@ int clusterAddNode(clusterNode *node)
  void clusterCron(void);
  clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask);
  
 +/* Scripting */
 +void scriptingInit(void);
 +
  /* Git SHA1 */
  char *redisGitSHA1(void);
  char *redisGitDirty(void);
@@@ -1217,8 -1214,6 +1228,8 @@@ void migrateCommand(redisClient *c)
  void dumpCommand(redisClient *c);
  void objectCommand(redisClient *c);
  void clientCommand(redisClient *c);
 +void evalCommand(redisClient *c);
 +void evalShaCommand(redisClient *c);
  
  #if defined(__GNUC__)
  void *calloc(size_t count, size_t size) __attribute__ ((deprecated));
diff --combined tests/test_helper.tcl
index e2a654285dd2165d965e336dd36af725fcfa5b37,e2a9e52524da91f7cb651c2c1dce4268a4802b8b..f505f26ae62f69d30bb87d9743882c99defac2d4
@@@ -110,6 -110,13 +110,13 @@@ proc cleanup {} 
  }
  
  proc execute_everything {} {
+     if 0 {
+         # Use this when hacking on new tests.
+         set ::verbose 1
+         execute_tests "unit/first"
+         return
+     }
      execute_tests "unit/printver"
      execute_tests "unit/auth"
      execute_tests "unit/protocol"
      execute_tests "integration/aof"
  #    execute_tests "integration/redis-cli"
      execute_tests "unit/pubsub"
 +    execute_tests "unit/scripting"
  
      return; # No diskstore tests for now...
      # run tests with diskstore enabled