mirror of
https://github.com/fluencelabs/redis
synced 2025-03-30 22:31:03 +00:00
postpone the AOF fsync if policy is everysec and there is a background fsync already going.
This commit is contained in:
parent
9a35eb22bf
commit
db3c2a4fb4
53
src/aof.c
53
src/aof.c
@ -18,7 +18,7 @@ void aof_background_fsync(int fd) {
|
|||||||
/* Called when the user switches from "appendonly yes" to "appendonly no"
|
/* Called when the user switches from "appendonly yes" to "appendonly no"
|
||||||
* at runtime using the CONFIG command. */
|
* at runtime using the CONFIG command. */
|
||||||
void stopAppendOnly(void) {
|
void stopAppendOnly(void) {
|
||||||
flushAppendOnlyFile();
|
flushAppendOnlyFile(1);
|
||||||
aof_fsync(server.appendfd);
|
aof_fsync(server.appendfd);
|
||||||
close(server.appendfd);
|
close(server.appendfd);
|
||||||
|
|
||||||
@ -63,12 +63,50 @@ int startAppendOnly(void) {
|
|||||||
* and the only way the client socket can get a write is entering when the
|
* and the only way the client socket can get a write is entering when the
|
||||||
* the event loop, we accumulate all the AOF writes in a memory
|
* the event loop, we accumulate all the AOF writes in a memory
|
||||||
* buffer and write it on disk using this function just before entering
|
* buffer and write it on disk using this function just before entering
|
||||||
* the event loop again. */
|
* the event loop again.
|
||||||
void flushAppendOnlyFile(void) {
|
*
|
||||||
|
* About the 'force' argument:
|
||||||
|
*
|
||||||
|
* When the fsync policy is set to 'everysec' we may delay the flush if there
|
||||||
|
* is still an fsync() going on in the background thread, since for instance
|
||||||
|
* on Linux write(2) will be blocked by the background fsync anyway.
|
||||||
|
* When this happens we remember that there is some aof buffer to be
|
||||||
|
* flushed ASAP, and will try to do that in the serverCron() function.
|
||||||
|
*
|
||||||
|
* However if force is set to 1 we'll write regardless of the background
|
||||||
|
* fsync. */
|
||||||
|
void flushAppendOnlyFile(int force) {
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
|
int sync_in_progress = 0;
|
||||||
|
|
||||||
if (sdslen(server.aofbuf) == 0) return;
|
if (sdslen(server.aofbuf) == 0) return;
|
||||||
|
|
||||||
|
if (server.appendfsync == APPENDFSYNC_EVERYSEC)
|
||||||
|
sync_in_progress = bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC) != 0;
|
||||||
|
|
||||||
|
if (server.appendfsync == APPENDFSYNC_EVERYSEC && !force) {
|
||||||
|
/* With this append fsync policy we do background fsyncing.
|
||||||
|
* If the fsync is still in progress we can try to delay
|
||||||
|
* the write for a couple of seconds. */
|
||||||
|
if (sync_in_progress) {
|
||||||
|
if (server.aof_flush_postponed_start == 0) {
|
||||||
|
/* No previous write postponinig, remember that we are
|
||||||
|
* postponing the flush and return. */
|
||||||
|
server.aof_flush_postponed_start = server.unixtime;
|
||||||
|
return;
|
||||||
|
} else if (server.unixtime - server.aof_flush_postponed_start < 2) {
|
||||||
|
/* We were already writing for fsync to finish, but for less
|
||||||
|
* than two seconds this is still ok. Postpone again. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Otherwise fall trough, and go write since we can't wait
|
||||||
|
* over two seconds. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If you are following this code path, then we are going to write so
|
||||||
|
* set reset the postponed flush sentinel to zero. */
|
||||||
|
server.aof_flush_postponed_start = 0;
|
||||||
|
|
||||||
/* We want to perform a single write. This should be guaranteed atomic
|
/* We want to perform a single write. This should be guaranteed atomic
|
||||||
* at least if the filesystem we are writing is a real physical one.
|
* at least if the filesystem we are writing is a real physical one.
|
||||||
* While this will save us against the server being killed I don't think
|
* While this will save us against the server being killed I don't think
|
||||||
@ -104,14 +142,15 @@ void flushAppendOnlyFile(void) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Perform the fsync if needed. */
|
/* Perform the fsync if needed. */
|
||||||
if (server.appendfsync == APPENDFSYNC_ALWAYS ||
|
if (server.appendfsync == APPENDFSYNC_ALWAYS) {
|
||||||
(server.appendfsync == APPENDFSYNC_EVERYSEC &&
|
|
||||||
server.unixtime > server.lastfsync))
|
|
||||||
{
|
|
||||||
/* aof_fsync is defined as fdatasync() for Linux in order to avoid
|
/* aof_fsync is defined as fdatasync() for Linux in order to avoid
|
||||||
* flushing metadata. */
|
* flushing metadata. */
|
||||||
aof_fsync(server.appendfd); /* Let's try to get this data on the disk */
|
aof_fsync(server.appendfd); /* Let's try to get this data on the disk */
|
||||||
server.lastfsync = server.unixtime;
|
server.lastfsync = server.unixtime;
|
||||||
|
} else if ((server.appendfsync == APPENDFSYNC_EVERYSEC &&
|
||||||
|
server.unixtime > server.lastfsync)) {
|
||||||
|
if (!sync_in_progress) aof_background_fsync(server.appendfd);
|
||||||
|
server.lastfsync = server.unixtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +697,11 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If we postponed an AOF buffer flush, let's try to do it every time the
|
||||||
|
* cron function is called. */
|
||||||
|
if (server.aof_flush_postponed_start) flushAppendOnlyFile(0);
|
||||||
|
|
||||||
/* Expire a few keys per cycle, only if this is a master.
|
/* Expire a few keys per cycle, only if this is a master.
|
||||||
* On slaves we wait for DEL operations synthesized by the master
|
* On slaves we wait for DEL operations synthesized by the master
|
||||||
* in order to guarantee a strict consistency. */
|
* in order to guarantee a strict consistency. */
|
||||||
@ -735,7 +740,7 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the AOF buffer on disk */
|
/* Write the AOF buffer on disk */
|
||||||
flushAppendOnlyFile();
|
flushAppendOnlyFile(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================== Server initialization ======================== */
|
/* =========================== Server initialization ======================== */
|
||||||
@ -822,6 +827,7 @@ void initServerConfig() {
|
|||||||
server.lastfsync = time(NULL);
|
server.lastfsync = time(NULL);
|
||||||
server.appendfd = -1;
|
server.appendfd = -1;
|
||||||
server.appendseldb = -1; /* Make sure the first time will not match */
|
server.appendseldb = -1; /* Make sure the first time will not match */
|
||||||
|
server.aof_flush_postponed_start = 0;
|
||||||
server.pidfile = zstrdup("/var/run/redis.pid");
|
server.pidfile = zstrdup("/var/run/redis.pid");
|
||||||
server.dbfilename = zstrdup("dump.rdb");
|
server.dbfilename = zstrdup("dump.rdb");
|
||||||
server.appendfilename = zstrdup("appendonly.aof");
|
server.appendfilename = zstrdup("appendonly.aof");
|
||||||
|
@ -559,6 +559,7 @@ struct redisServer {
|
|||||||
time_t lastfsync;
|
time_t lastfsync;
|
||||||
int appendfd;
|
int appendfd;
|
||||||
int appendseldb;
|
int appendseldb;
|
||||||
|
time_t aof_flush_postponed_start;
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
pid_t bgsavechildpid;
|
pid_t bgsavechildpid;
|
||||||
pid_t bgrewritechildpid;
|
pid_t bgrewritechildpid;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user