Skip to content

Commit

Permalink
log: use fdatasync instead of fsync where possible
Browse files Browse the repository at this point in the history
Using years-old benchmark attached to PostreSQL ML[1], I've observed
tiny bit more than double boost in speed when using fdatasync instead of
traditional fsync, on two Linux machines, each equipped with an SSD.
While the observation may be disputable (there are various
interpretations to what "synchronized I/O" actually means), by logical
extension of what the two are supposed to do, one can expect fdatasync
will perform no worse than fsync.  Having the timestamps correct is
really not a priority, compared to timely processing of the message
stream.  So let's use it whenever possible with QB_LOG_CONF_FILE_SYNC
requested.

As an aside, PostreSQL seems to be be using "fdatasync" method of
updating out to disk by default on Linux till today[2].

[1] https://www.postgresql.org/message-id/[email protected]
    https://www.postgresql.org/message-id/attachment/20659/syncbench.c
[2] https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-WAL-SYNC-METHOD

Signed-off-by: Jan Pokorný <[email protected]>
  • Loading branch information
jnpkrn committed Jul 31, 2017
1 parent ef4c3a1 commit 55efe05
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
33 changes: 30 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,10 @@ AC_FUNC_CHOWN
AC_FUNC_FORK
AC_FUNC_MMAP
AC_FUNC_STRERROR_R
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \
localtime localtime_r memset munmap socket \
AC_CHECK_FUNCS([alarm clock_gettime \
fsync fdatasync ftruncate \
gettimeofday localtime localtime_r \
memset munmap socket \
strchr strrchr strdup strstr strcasecmp \
poll epoll_create epoll_create1 kqueue \
random rand getrlimit sysconf \
Expand Down Expand Up @@ -270,6 +272,7 @@ fi

nongcc_memory_barrier_needed=no
arch_force_shmlba=no
file_sync=fdatasync
AC_MSG_CHECKING([for architecture in ${host_cpu}])
case $host_cpu in
sparc*)
Expand Down Expand Up @@ -388,6 +391,30 @@ case "$host_os" in
;;
esac

dnl iterated fallback scheme, break on first hit, fallthrough otherwise, until
dnl empty or unsupported string reached; output QB_FILE_SYNC macro supposed
dnl to operate on a file descriptor passed as its only argument
while : ; do
case ${file_sync} in
fdatasync)
test "x${ac_cv_func_fdatasync}" = x || break
file_sync=fsync;;
fsync)
test "x${ac_cv_func_fsync}" = x || break
file_sync=;;
"")
break;;
*)
AC_MSG_ERROR([Cannot select file sync method]);;
esac
done
if test "x${file_sync}" != x; then
AC_DEFINE_UNQUOTED([QB_FILE_SYNC(fd)], [${file_sync}(fd)], [File sync method])
else
AC_MSG_WARN([No file sync method applicable!])
AC_DEFINE([QB_FILE_SYNC(x)], [], [File sync method])
fi

AC_MSG_CHECKING([whether GCC supports builtin sync intrinsics])
if test -z "$gcc_has_builtin_sync_operations"; then
gcc_has_builtin_sync_operations=no
Expand Down Expand Up @@ -709,7 +736,7 @@ AC_MSG_RESULT([ Arch-independent files = ${datadir}])
AC_MSG_RESULT([ State information = ${localstatedir}])
AC_MSG_RESULT([ System configuration = ${sysconfdir}])
AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}])
AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}])
AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}])
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE build info:])
AC_MSG_RESULT([ Optimization = ${OPT_CFLAGS}])
Expand Down
2 changes: 1 addition & 1 deletion lib/log_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ _file_logger(int32_t t,

fflush(f);
if (target->file_sync) {
fsync(fileno(f));
QB_FILE_SYNC(fileno(f));
}
}

Expand Down

0 comments on commit 55efe05

Please sign in to comment.