From 55efe05c918752847cd6f05f4831138fde7af583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= Date: Thu, 27 Jul 2017 22:52:03 +0200 Subject: [PATCH] log: use fdatasync instead of fsync where possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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/1095055866.414539fadb90d@webmail.rawbw.com 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ý --- configure.ac | 33 ++++++++++++++++++++++++++++++--- lib/log_file.c | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index ff7133e83..28dd1b6b2 100644 --- a/configure.ac +++ b/configure.ac @@ -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 \ @@ -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*) @@ -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 @@ -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}]) diff --git a/lib/log_file.c b/lib/log_file.c index 8f1a94b9a..42f1398dd 100644 --- a/lib/log_file.c +++ b/lib/log_file.c @@ -40,7 +40,7 @@ _file_logger(int32_t t, fflush(f); if (target->file_sync) { - fsync(fileno(f)); + QB_FILE_SYNC(fileno(f)); } }