Hi,

We allow $SUBJECT on Windows.  I'm not sure exactly how we finished up
with that, maybe a historical mistake, but I find it misleading today.
Modern Windows flushes drive write caches for fsync (= _commit()) and
fdatasync (= FLUSH_FLAGS_FILE_DATA_SYNC_ONLY).  In fact it is possible
to tell Windows to write out file data without flushing the drive
cache (= FLUSH_FLAGS_NO_SYNC), but I don't believe anyone is
interested in new weaker levels.  Any reason not to just get rid of
it?

On macOS, our fsync and fdatasync levels *don't* flush drive caches,
because those system calls don't on that OS, and they offer a weird
special fcntl, so there we offer $SUBJECT for a good reason.  Now that
macOS 10.2 systems are thoroughly extinct, I think we might as well
drop the configure probe, though, while we're doing a lot of that sort
of thing.

The documentation also says a couple of things that aren't quite
correct about wal_sync_level.  (I would also like to revise other
nearby outdated paragraphs about volatile write caches, sector sizes
etc, but that'll take some more research.)
From 42bd2d6c0ff4cd931ec3d4008438842bab5acd4b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 26 Aug 2022 14:27:43 +1200
Subject: [PATCH 1/3] Remove wal_sync_method=fsync_writethrough on Windows.

The fsync and fdatasync levels already flush drive write caches on
Windows, so it only confuses matters to have an apparently higher level
that isn't actually higher.  We don't do that on any other OS.
---
 doc/src/sgml/wal.sgml                 | 5 ++---
 src/backend/storage/file/fd.c         | 6 ++----
 src/bin/pg_test_fsync/pg_test_fsync.c | 4 +---
 src/include/port/win32_port.h         | 8 --------
 4 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
index 01f7379ebb..90cbacfe41 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -108,9 +108,8 @@
         <literal>open_datasync</literal> (the default), write caching can be disabled
         by unchecking <literal>My Computer\Open\<replaceable>disk drive</replaceable>\Properties\Hardware\Properties\Policies\Enable write caching on the disk</literal>.
         Alternatively, set <varname>wal_sync_method</varname> to
-        <literal>fdatasync</literal> (NTFS only), <literal>fsync</literal> or
-        <literal>fsync_writethrough</literal>, which prevent
-        write caching.
+        <literal>fdatasync</literal> (NTFS only) or <literal>fsync</literal>,
+        which prevent write caching.
       </para>
     </listitem>
 
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index e3b19ca1ed..c27a6600fe 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -395,7 +395,7 @@ pg_fsync(int fd)
 #endif
 
 	/* #if is to skip the sync_method test if there's no need for it */
-#if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
+#if defined(HAVE_FSYNC_WRITETHROUGH)
 	if (sync_method == SYNC_METHOD_FSYNC_WRITETHROUGH)
 		return pg_fsync_writethrough(fd);
 	else
@@ -425,9 +425,7 @@ pg_fsync_writethrough(int fd)
 {
 	if (enableFsync)
 	{
-#ifdef WIN32
-		return _commit(fd);
-#elif defined(F_FULLFSYNC)
+#if defined(F_FULLFSYNC)
 		return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
 #else
 		errno = ENOSYS;
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 77f0db0376..e23e2601ad 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -605,9 +605,7 @@ signal_cleanup(int signum)
 static int
 pg_fsync_writethrough(int fd)
 {
-#ifdef WIN32
-	return _commit(fd);
-#elif defined(F_FULLFSYNC)
+#if defined(F_FULLFSYNC)
 	return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
 #else
 	errno = ENOSYS;
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 707f8760ca..b6769a1693 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -75,14 +75,6 @@
 /* Windows doesn't have fsync() as such, use _commit() */
 #define fsync(fd) _commit(fd)
 
-/*
- * For historical reasons, we allow setting wal_sync_method to
- * fsync_writethrough on Windows, even though it's really identical to fsync
- * (both code paths wind up at _commit()).
- */
-#define HAVE_FSYNC_WRITETHROUGH
-#define FSYNC_WRITETHROUGH_IS_FSYNC
-
 #define USES_WINSOCK
 
 /*
-- 
2.35.1

From 6e59fb92aafa4803ceed411e1610a4f458ed092b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 26 Aug 2022 15:00:26 +1200
Subject: [PATCH 2/3] Remove configure probe for F_FULLSYNC.

This was done to avoid using it on very old macOS systems.
---
 configure                  | 14 --------------
 configure.ac               |  3 ---
 src/include/pg_config.h.in |  4 ----
 src/include/port/darwin.h  |  3 ---
 src/tools/msvc/Solution.pm |  1 -
 5 files changed, 25 deletions(-)

diff --git a/configure b/configure
index a268780c5d..6975c3f0ca 100755
--- a/configure
+++ b/configure
@@ -16204,20 +16204,6 @@ esac
 fi
 
 
-# This is probably only present on macOS, but may as well check always
-ac_fn_c_check_decl "$LINENO" "F_FULLFSYNC" "ac_cv_have_decl_F_FULLFSYNC" "#include <fcntl.h>
-"
-if test "x$ac_cv_have_decl_F_FULLFSYNC" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_F_FULLFSYNC $ac_have_decl
-_ACEOF
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PS_STRINGS" >&5
 $as_echo_n "checking for PS_STRINGS... " >&6; }
 if ${pgac_cv_var_PS_STRINGS+:} false; then :
diff --git a/configure.ac b/configure.ac
index 993b5d5cb0..e293bfdfb7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1798,9 +1798,6 @@ AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
 AC_CHECK_DECLS([preadv], [], [AC_LIBOBJ(preadv)], [#include <sys/uio.h>])
 AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include <sys/uio.h>])
 
-# This is probably only present on macOS, but may as well check always
-AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
-
 AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
 [AC_LINK_IFELSE([AC_LANG_PROGRAM(
 [#include <machine/vmparam.h>
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c5a80b829e..6d1e2c2904 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -95,10 +95,6 @@
    don't. */
 #undef HAVE_DECL_FDATASYNC
 
-/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you
-   don't. */
-#undef HAVE_DECL_F_FULLFSYNC
-
 /* Define to 1 if you have the declaration of
    `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */
 #undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
diff --git a/src/include/port/darwin.h b/src/include/port/darwin.h
index 15fb69d6db..36c54b2152 100644
--- a/src/include/port/darwin.h
+++ b/src/include/port/darwin.h
@@ -2,7 +2,4 @@
 
 #define __darwin__	1
 
-#if HAVE_DECL_F_FULLFSYNC		/* not present before macOS 10.3 */
 #define HAVE_FSYNC_WRITETHROUGH
-
-#endif
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index c2acb58df0..86dfa9faa6 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -233,7 +233,6 @@ sub GenerateFiles
 		HAVE_CRTDEFS_H             => undef,
 		HAVE_CRYPTO_LOCK           => undef,
 		HAVE_DECL_FDATASYNC        => 0,
-		HAVE_DECL_F_FULLFSYNC      => 0,
 		HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER => 0,
 		HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER    => 0,
 		HAVE_DECL_LLVMGETHOSTCPUNAME                => 0,
-- 
2.35.1

From 136dd36dd2604daf0f7402e4fcd280415f61f005 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 26 Aug 2022 16:05:59 +1200
Subject: [PATCH 3/3] Doc: Corrections to claims about wal_sync_method.

We claimed that fsync_writethrough called fsync() and then flushed write
caches, but that is untrue.  Describe the actual system call, and
mention that it's macOS-only.

We claimed that all the wal_sync_method values were equally reliable,
except that fsync_writethrough might flush write caches.  In fact
open_[data]sync might differ from f[data]sync on several systems in
terms of power loss risk, depending on whether the filesystem tries to
use FUA, whether the driver passes it on, and whether the device honors
it.  That's too technical a topic to go into here, but let's remove the
misleading statement.

We talked about "preventing caching" when we meant "flushing caches".

We said that open_[data]sync would get you O_DIRECT where available, but
that is not generally true.  It is true only with wal_level=minimal and
max_wal_senders=0, which must surely be a very rare configuration.
---
 doc/src/sgml/config.sgml |  3 +--
 doc/src/sgml/wal.sgml    | 10 ++++------
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index a5cd4e44c7..eac0a1c8fe 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3061,7 +3061,7 @@ include_dir 'conf.d'
         </listitem>
         <listitem>
         <para>
-         <literal>fsync_writethrough</literal> (call <function>fsync()</function> at each commit, forcing write-through of any disk write cache)
+         <literal>fsync_writethrough</literal> (macOS only: call <function>fcntl(F_FULLSYNC)</function> at each commit, flushing any disk write cache)
         </para>
         </listitem>
         <listitem>
@@ -3071,7 +3071,6 @@ include_dir 'conf.d'
         </listitem>
        </itemizedlist>
        <para>
-        The <literal>open_</literal>* options also use <literal>O_DIRECT</literal> if available.
         Not all of these choices are available on all platforms.
         The default is the first method in the above list that is supported
         by the platform, except that <literal>fdatasync</literal> is the default on
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
index 90cbacfe41..cf5f4c41d9 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -109,13 +109,13 @@
         by unchecking <literal>My Computer\Open\<replaceable>disk drive</replaceable>\Properties\Hardware\Properties\Policies\Enable write caching on the disk</literal>.
         Alternatively, set <varname>wal_sync_method</varname> to
         <literal>fdatasync</literal> (NTFS only) or <literal>fsync</literal>,
-        which prevent write caching.
+        which flush write caches.
       </para>
     </listitem>
 
     <listitem>
       <para>
-        On <productname>macOS</productname>, write caching can be prevented by
+        On <productname>macOS</productname>, write caches can be flushed by
         setting <varname>wal_sync_method</varname> to <literal>fsync_writethrough</literal>.
       </para>
     </listitem>
@@ -756,10 +756,8 @@
    The <xref linkend="guc-wal-sync-method"/> parameter determines how
    <productname>PostgreSQL</productname> will ask the kernel to force
    <acronym>WAL</acronym> updates out to disk.
-   All the options should be the same in terms of reliability, with
-   the exception of <literal>fsync_writethrough</literal>, which can sometimes
-   force a flush of the disk cache even when other options do not do so.
-   However, it's quite platform-specific which one will be the fastest.
+   It is platform-specific, and some cases also device-specific, which options
+   flush or write through volatile write caches.
    You can test the speeds of different options using the <xref
    linkend="pgtestfsync"/> program.
    Note that this parameter is irrelevant if <varname>fsync</varname>
-- 
2.35.1

Reply via email to