summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2019-04-29 14:38:28 +0800
committerzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2019-04-29 14:38:28 +0800
commitbcac165fabcbec43843800e3f2fcb69a201d8b50 (patch)
treee862fd85a3f2ed41afd378d86c45ec68a4b0f23a
parent843de8b786562d8d77c78d83a971060adc61f77a (diff)
downloadredis-bcac165fabcbec43843800e3f2fcb69a201d8b50.tar.gz
aof: enhance AOF_FSYNC_EVERYSEC, more details in #5985
-rw-r--r--src/aof.c34
-rw-r--r--src/server.h1
2 files changed, 32 insertions, 3 deletions
diff --git a/src/aof.c b/src/aof.c
index 615eebd01..4744847d2 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -197,6 +197,12 @@ ssize_t aofRewriteBufferWrite(int fd) {
* AOF file implementation
* ------------------------------------------------------------------------- */
+/* Return true if an AOf fsync is currently already in progress in a
+ * BIO thread. */
+int aofFsyncInProgress(void) {
+ return bioPendingJobsOfType(BIO_AOF_FSYNC) != 0;
+}
+
/* Starts a background task that performs fsync() against the specified
* file descriptor (the one of the AOF file) in another thread. */
void aof_background_fsync(int fd) {
@@ -335,10 +341,24 @@ void flushAppendOnlyFile(int force) {
int sync_in_progress = 0;
mstime_t latency;
- if (sdslen(server.aof_buf) == 0) return;
+ if (sdslen(server.aof_buf) == 0) {
+ /* Check if we need to do fsync even the aof buffer is empty,
+ * because previously in AOF_FSYNC_EVERYSEC mode, fsync is
+ * called only when aof buffer is not empty, so if users
+ * stop write commands before fsync called in one second,
+ * the data in page cache cannot be flushed in time. */
+ if (server.aof_fsync == AOF_FSYNC_EVERYSEC &&
+ server.aof_fsync_offset != server.aof_current_size &&
+ server.unixtime > server.aof_last_fsync &&
+ !(sync_in_progress = aofFsyncInProgress())) {
+ goto try_fsync;
+ } else {
+ return;
+ }
+ }
if (server.aof_fsync == AOF_FSYNC_EVERYSEC)
- sync_in_progress = bioPendingJobsOfType(BIO_AOF_FSYNC) != 0;
+ sync_in_progress = aofFsyncInProgress();
if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) {
/* With this append fsync policy we do background fsyncing.
@@ -470,6 +490,7 @@ void flushAppendOnlyFile(int force) {
server.aof_buf = sdsempty();
}
+try_fsync:
/* Don't fsync if no-appendfsync-on-rewrite is set to yes and there are
* children doing I/O in the background. */
if (server.aof_no_fsync_on_rewrite &&
@@ -484,10 +505,14 @@ void flushAppendOnlyFile(int force) {
redis_fsync(server.aof_fd); /* Let's try to get this data on the disk */
latencyEndMonitor(latency);
latencyAddSampleIfNeeded("aof-fsync-always",latency);
+ server.aof_fsync_offset = server.aof_current_size;
server.aof_last_fsync = server.unixtime;
} else if ((server.aof_fsync == AOF_FSYNC_EVERYSEC &&
server.unixtime > server.aof_last_fsync)) {
- if (!sync_in_progress) aof_background_fsync(server.aof_fd);
+ if (!sync_in_progress) {
+ aof_background_fsync(server.aof_fd);
+ server.aof_fsync_offset = server.aof_current_size;
+ }
server.aof_last_fsync = server.unixtime;
}
}
@@ -694,6 +719,7 @@ int loadAppendOnlyFile(char *filename) {
* operation is received. */
if (fp && redis_fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) {
server.aof_current_size = 0;
+ server.aof_fsync_offset = server.aof_current_size;
fclose(fp);
return C_ERR;
}
@@ -832,6 +858,7 @@ loaded_ok: /* DB loaded, cleanup and return C_OK to the caller. */
stopLoading();
aofUpdateCurrentSize();
server.aof_rewrite_base_size = server.aof_current_size;
+ server.aof_fsync_offset = server.aof_current_size;
return C_OK;
readerr: /* Read error. If feof(fp) is true, fall through to unexpected EOF. */
@@ -1741,6 +1768,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
server.aof_selected_db = -1; /* Make sure SELECT is re-issued */
aofUpdateCurrentSize();
server.aof_rewrite_base_size = server.aof_current_size;
+ server.aof_current_size = server.aof_current_size;
/* Clear regular AOF buffer since its contents was just written to
* the new AOF from the background rewrite buffer. */
diff --git a/src/server.h b/src/server.h
index dfd9f7698..e7f01b2ef 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1140,6 +1140,7 @@ struct redisServer {
off_t aof_rewrite_min_size; /* the AOF file is at least N bytes. */
off_t aof_rewrite_base_size; /* AOF size on latest startup or rewrite. */
off_t aof_current_size; /* AOF current size. */
+ off_t aof_fsync_offset; /* AOF offset which is already synced to disk. */
int aof_rewrite_scheduled; /* Rewrite once BGSAVE terminates. */
pid_t aof_child_pid; /* PID if rewriting process */
list *aof_rewrite_buf_blocks; /* Hold changes during an AOF rewrite. */