#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
+/* Append only defines */
+#define APPENDFSYNC_NO 0
+#define APPENDFSYNC_ALWAYS 1
+#define APPENDFSYNC_EVERYSEC 2
+
/*================================= Data types ============================== */
/* A redis object, that is a type able to hold a string / list / set */
int dbnum;
int daemonize;
int appendonly;
+ int appendfsync;
+ time_t lastfsync;
int appendfd;
int appendseldb;
char *pidfile;
server.glueoutputbuf = 1;
server.daemonize = 0;
server.appendonly = 0;
+ server.appendfsync = APPENDFSYNC_EVERYSEC;
+ server.lastfsync = time(NULL);
server.appendfd = -1;
server.appendseldb = -1; /* Make sure the first time will not match */
server.pidfile = "/var/run/redis.pid";
if ((server.appendonly = 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;
+ } else if (strcasecmp(argv[1],"always")) {
+ server.appendfsync = APPENDFSYNC_ALWAYS;
+ } else if (strcasecmp(argv[1],"everysec")) {
+ server.appendfsync = APPENDFSYNC_EVERYSEC;
+ } else {
+ err = "argument must be 'no', 'always' or 'everysec'";
+ goto loaderr;
+ }
} else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
server.requirepass = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"pidfile") && argc == 2) {
sds buf = sdsempty();
int j;
ssize_t nwritten;
+ time_t now;
/* The DB this command was targetting is not the same as the last command
* we appendend. To issue a SELECT command is needed. */
redisLog(REDIS_WARNING,"Aborting on short write while writing to the append-only file: %s",strerror(errno));
}
abort();
- }
- fsync(server.appendfd); /* Let's try to get this data on the disk */
+ }
+ now = time(NULL);
+ if (server.appendfsync == APPENDFSYNC_ALWAYS ||
+ (server.appendfsync == APPENDFSYNC_EVERYSEC &&
+ now-server.lastfsync > 1))
+ {
+ fsync(server.appendfd); /* Let's try to get this data on the disk */
+ server.lastfsync = now;
+ }
}
static void processInputBuffer(redisClient *c) {
# appendonly yes
+# The fsync() calls tells the Operating System to actually write data on disk
+# instead to wait for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log . Slow, Safest.
+# everysec: fsync only if one second passed since the last fsync. Compromise.
+#
+# The default is "no" since it's faster and anyway safer than snapshots from
+# the point of view of durability of the latest records modified.
+
+appendfsync no
+# appendfsync always
+# appendfsync everysec
+
############################### ADVANCED CONFIG ###############################
# Glue small output buffers together in order to send small replies in a