]> git.saurik.com Git - redis.git/commitdiff
Merge branch 'no-appendfsync-on-rewrite'
authorantirez <antirez@gmail.com>
Mon, 31 May 2010 08:08:14 +0000 (10:08 +0200)
committerantirez <antirez@gmail.com>
Mon, 31 May 2010 08:08:14 +0000 (10:08 +0200)
1  2 
redis.c

diff --combined redis.c
index 92ae07b7f60e847daf87e9b623e6837db8c5ab72,8c4e3ab232dd6f144e3a7e8e712d1bc24cbf43fb..949bb58eac20d52c96a953747abdcd5855e05921
+++ b/redis.c
@@@ -369,6 -369,7 +369,7 @@@ struct redisServer 
      int daemonize;
      int appendonly;
      int appendfsync;
+     int no_appendfsync_on_rewrite;
      int shutdown_asap;
      time_t lastfsync;
      int appendfd;
@@@ -752,8 -753,7 +753,8 @@@ static void unwatchCommand(redisClient 
  
  /* Global vars */
  static struct redisServer server; /* server global state */
 -static struct redisCommand cmdTable[] = {
 +static struct redisCommand *commandTable;
 +static struct redisCommand readonlyCommandTable[] = {
      {"get",getCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
      {"set",setCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,0,0,0},
      {"setnx",setnxCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,0,0,0},
      {"punsubscribe",punsubscribeCommand,-1,REDIS_CMD_INLINE,NULL,0,0,0},
      {"publish",publishCommand,3,REDIS_CMD_BULK|REDIS_CMD_FORCE_REPLICATION,NULL,0,0,0},
      {"watch",watchCommand,-2,REDIS_CMD_INLINE,NULL,0,0,0},
 -    {"unwatch",unwatchCommand,1,REDIS_CMD_INLINE,NULL,0,0,0},
 -    {NULL,NULL,0,0,NULL,0,0,0}
 +    {"unwatch",unwatchCommand,1,REDIS_CMD_INLINE,NULL,0,0,0}
  };
  
  /*============================ Utility functions ============================ */
@@@ -1385,7 -1386,7 +1386,7 @@@ void backgroundRewriteDoneHandler(int s
              /* If append only is actually enabled... */
              close(server.appendfd);
              server.appendfd = fd;
-             fsync(fd);
+             if (server.appendfsync != APPENDFSYNC_NO) aof_fsync(fd);
              server.appendseldb = -1; /* Make sure it will issue SELECT */
              redisLog(REDIS_NOTICE,"The new append only file was selected for future appends.");
          } else {
@@@ -1685,6 -1686,7 +1686,7 @@@ static void initServerConfig() 
      server.daemonize = 0;
      server.appendonly = 0;
      server.appendfsync = APPENDFSYNC_EVERYSEC;
+     server.no_appendfsync_on_rewrite = 0;
      server.lastfsync = time(NULL);
      server.appendfd = -1;
      server.appendseldb = -1; /* Make sure the first time will not match */
@@@ -1941,6 -1943,11 +1943,11 @@@ static void loadServerConfig(char *file
          } else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
              zfree(server.appendfilename);
              server.appendfilename = zstrdup(argv[1]);
+         } else if (!strcasecmp(argv[0],"no-appendfsync-on-rewrite")
+                    && argc == 2) {
+             if ((server.no_appendfsync_on_rewrite= yesnotoi(argv[1])) == -1) {
+                 err = "argument must be 'yes' or 'no'"; goto loaderr;
+             }
          } else if (!strcasecmp(argv[0],"appendfsync") && argc == 2) {
              if (!strcasecmp(argv[1],"no")) {
                  server.appendfsync = APPENDFSYNC_NO;
@@@ -2247,29 -2254,13 +2254,29 @@@ static void sendReplyToClientWritev(aeE
      }
  }
  
 +static int qsortRedisCommands(const void *r1, const void *r2) {
 +    return strcasecmp(
 +        ((struct redisCommand*)r1)->name,
 +        ((struct redisCommand*)r2)->name);
 +}
 +
 +static void sortCommandTable() {
 +    /* Copy and sort the read-only version of the command table */
 +    commandTable = (struct redisCommand*)malloc(sizeof(readonlyCommandTable));
 +    memcpy(commandTable,readonlyCommandTable,sizeof(readonlyCommandTable));
 +    qsort(commandTable,
 +        sizeof(readonlyCommandTable)/sizeof(struct redisCommand),
 +        sizeof(struct redisCommand),qsortRedisCommands);
 +}
 +
  static struct redisCommand *lookupCommand(char *name) {
 -    int j = 0;
 -    while(cmdTable[j].name != NULL) {
 -        if (!strcasecmp(name,cmdTable[j].name)) return &cmdTable[j];
 -        j++;
 -    }
 -    return NULL;
 +    struct redisCommand tmp = {name,NULL,0,0,NULL,0,0,0};
 +    return bsearch(
 +        &tmp,
 +        commandTable,
 +        sizeof(readonlyCommandTable)/sizeof(struct redisCommand),
 +        sizeof(struct redisCommand),
 +        qsortRedisCommands);
  }
  
  /* resetClient prepare the client to process the next command */
@@@ -4209,7 -4200,7 +4216,7 @@@ static int prepareForShutdown() 
      }
      if (server.appendonly) {
          /* Append only file: fsync() the AOF and exit */
-         fsync(server.appendfd);
+         aof_fsync(server.appendfd);
          if (server.vm_enabled) unlink(server.vm_swap_file);
      } else {
          /* Snapshotting. Perform a SYNC SAVE and exit */
@@@ -5750,11 -5741,6 +5757,11 @@@ static void zaddGenericCommand(redisCli
      zset *zs;
      double *score;
  
 +    if (isnan(scoreval)) {
 +        addReplySds(c,sdsnew("-ERR provide score is Not A Number (nan)\r\n"));
 +        return;
 +    }
 +
      zsetobj = lookupKeyWrite(c->db,key);
      if (zsetobj == NULL) {
          zsetobj = createZsetObject();
          } else {
              *score = scoreval;
          }
 +        if (isnan(*score)) {
 +            addReplySds(c,
 +                sdsnew("-ERR resulting score is Not A Number (nan)\r\n"));
 +            zfree(score);
 +            /* Note that we don't need to check if the zset may be empty and
 +             * should be removed here, as we can only obtain Nan as score if
 +             * there was already an element in the sorted set. */
 +            return;
 +        }
      } else {
          *score = scoreval;
      }
@@@ -8266,6 -8243,11 +8273,11 @@@ static void flushAppendOnlyFile(void) 
      sdsfree(server.aofbuf);
      server.aofbuf = sdsempty();
  
+     /* Don't Fsync if no-appendfsync-on-rewrite is set to yes and we have
+      * childs performing heavy I/O on disk. */
+     if (server.no_appendfsync_on_rewrite &&
+         (server.bgrewritechildpid != -1 || server.bgsavechildpid != -1))
+             return;
      /* Fsync if needed */
      now = time(NULL);
      if (server.appendfsync == APPENDFSYNC_ALWAYS ||
@@@ -8704,7 -8686,7 +8716,7 @@@ static int rewriteAppendOnlyFile(char *
  
      /* Make sure data will not remain on the OS's output buffers */
      fflush(fp);
-     fsync(fileno(fp));
+     aof_fsync(fileno(fp));
      fclose(fp);
  
      /* Use RENAME to make sure the DB file is changed atomically only
@@@ -8821,7 -8803,7 +8833,7 @@@ static void aofRemoveTempFile(pid_t chi
   * at runtime using the CONFIG command. */
  static void stopAppendOnly(void) {
      flushAppendOnlyFile();
-     fsync(server.appendfd);
+     aof_fsync(server.appendfd);
      close(server.appendfd);
  
      server.appendfd = -1;
@@@ -9990,6 -9972,11 +10002,11 @@@ static void configSetCommand(redisClien
          } else {
              goto badfmt;
          }
+     } else if (!strcasecmp(c->argv[2]->ptr,"no-appendfsync-on-rewrite")) {
+         int yn = yesnotoi(o->ptr);
+         if (yn == -1) goto badfmt;
+         server.no_appendfsync_on_rewrite = yn;
      } else if (!strcasecmp(c->argv[2]->ptr,"appendonly")) {
          int old = server.appendonly;
          int new = yesnotoi(o->ptr);
@@@ -10105,6 -10092,11 +10122,11 @@@ static void configGetCommand(redisClien
          addReplyBulkCString(c,server.appendonly ? "yes" : "no");
          matches++;
      }
+     if (stringmatch(pattern,"no-appendfsync-on-rewrite",0)) {
+         addReplyBulkCString(c,"no-appendfsync-on-rewrite");
+         addReplyBulkCString(c,server.no_appendfsync_on_rewrite ? "yes" : "no");
+         matches++;
+     }
      if (stringmatch(pattern,"appendfsync",0)) {
          char *policy;
  
@@@ -10951,7 -10943,6 +10973,7 @@@ int main(int argc, char **argv) 
      time_t start;
  
      initServerConfig();
 +    sortCommandTable();
      if (argc == 2) {
          if (strcmp(argv[1], "-v") == 0 ||
              strcmp(argv[1], "--version") == 0) version();