| 358 | * fsync. */ |
| 359 | #define AOF_WRITE_LOG_ERROR_RATE 30 /* Seconds between errors logging. */ |
| 360 | void flushAppendOnlyFile(int force) { |
| 361 | ssize_t nwritten; |
| 362 | int sync_in_progress = 0; |
| 363 | mstime_t latency; |
| 364 | |
| 365 | if (sdslen(server.aof_buf) == 0) { |
| 366 | /* Check if we need to do fsync even the aof buffer is empty, |
| 367 | * because previously in AOF_FSYNC_EVERYSEC mode, fsync is |
| 368 | * called only when aof buffer is not empty, so if users |
| 369 | * stop write commands before fsync called in one second, |
| 370 | * the data in page cache cannot be flushed in time. */ |
| 371 | if (server.aof_fsync == AOF_FSYNC_EVERYSEC && |
| 372 | server.aof_fsync_offset != server.aof_current_size && |
| 373 | server.unixtime > server.aof_last_fsync && |
| 374 | !(sync_in_progress = aofFsyncInProgress())) { |
| 375 | goto try_fsync; |
| 376 | } else { |
| 377 | return; |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | if (server.aof_fsync == AOF_FSYNC_EVERYSEC) |
| 382 | sync_in_progress = aofFsyncInProgress(); |
| 383 | |
| 384 | if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) { |
| 385 | /* With this append fsync policy we do background fsyncing. |
| 386 | * If the fsync is still in progress we can try to delay |
| 387 | * the write for a couple of seconds. */ |
| 388 | if (sync_in_progress) { |
| 389 | if (server.aof_flush_postponed_start == 0) { |
| 390 | /* No previous write postponing, remember that we are |
| 391 | * postponing the flush and return. */ |
| 392 | server.aof_flush_postponed_start = server.unixtime; |
| 393 | return; |
| 394 | } else if (server.unixtime - server.aof_flush_postponed_start < 2) { |
| 395 | /* We were already waiting for fsync to finish, but for less |
| 396 | * than two seconds this is still ok. Postpone again. */ |
| 397 | return; |
| 398 | } |
| 399 | /* Otherwise fall trough, and go write since we can't wait |
| 400 | * over two seconds. */ |
| 401 | server.aof_delayed_fsync++; |
| 402 | serverLog(LL_NOTICE,"Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis."); |
| 403 | } |
| 404 | } |
| 405 | /* We want to perform a single write. This should be guaranteed atomic |
| 406 | * at least if the filesystem we are writing is a real physical one. |
| 407 | * While this will save us against the server being killed I don't think |
| 408 | * there is much to do about the whole server stopping for power problems |
| 409 | * or alike */ |
| 410 | |
| 411 | if (server.aof_flush_sleep && sdslen(server.aof_buf)) { |
| 412 | usleep(server.aof_flush_sleep); |
| 413 | } |
| 414 | |
| 415 | latencyStartMonitor(latency); |
| 416 | nwritten = aofWrite(server.aof_fd,server.aof_buf,sdslen(server.aof_buf)); |
| 417 | latencyEndMonitor(latency); |
no test coverage detected