]> granicus.if.org Git - postgresql/commitdiff
Force default wal_sync_method to be fdatasync on Linux.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 9 Dec 2010 01:01:33 +0000 (20:01 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 9 Dec 2010 01:01:33 +0000 (20:01 -0500)
Recent versions of the Linux system header files cause xlogdefs.h to
believe that open_datasync should be the default sync method, whereas
formerly fdatasync was the default on Linux.  open_datasync is a bad
choice, first because it doesn't actually outperform fdatasync (in fact
the reverse), and second because we try to use O_DIRECT with it, causing
failures on certain filesystems (e.g., ext4 with data=journal option).
This part of the patch is largely per a proposal from Marti Raudsepp.
More extensive changes are likely to follow in HEAD, but this is as much
change as we want to back-patch.

Also clean up confusing code and incorrect documentation surrounding the
fsync_writethrough option.  Those changes shouldn't result in any actual
behavioral change, but I chose to back-patch them anyway to keep the
branches looking similar in this area.

In 9.0 and HEAD, also do some copy-editing on the WAL Reliability
documentation section.

Back-patch to all supported branches, since any of them might get used
on modern Linux versions.

doc/src/sgml/config.sgml
src/backend/access/transam/xlog.c
src/backend/storage/file/fd.c
src/backend/utils/misc/postgresql.conf.sample
src/include/port/linux.h
src/include/port/win32.h

index ea9192625cc8f6108991d13444ccabce24162ac9..ecee5507c266b92e66fb59aa4423951afa939a8a 100644 (file)
@@ -1347,12 +1347,12 @@ SET ENABLE_SEQSCAN TO OFF;
         </listitem>
         <listitem>
         <para>
-         <literal>fsync_writethrough</> (call <function>fsync()</> at each commit, forcing write-through of any disk write cache)
+         <literal>fsync</> (call <function>fsync()</> at each commit)
         </para>
         </listitem>
         <listitem>
         <para>
-         <literal>fsync</> (call <function>fsync()</> at each commit)
+         <literal>fsync_writethrough</> (call <function>fsync()</> at each commit, forcing write-through of any disk write cache)
         </para>
         </listitem>
         <listitem>
@@ -1363,7 +1363,9 @@ SET ENABLE_SEQSCAN TO OFF;
        </itemizedlist>
        <para>
         Not all of these choices are available on all platforms.
-        The default is the first method in the above list that is supported.
+        The default is the first method in the above list that is supported
+        by the platform, except that <literal>fdatasync</> is the default on
+        Linux.
         This option can be set at server start or in the
         <filename>postgresql.conf</filename> file.
        </para>
index a8fdf4078095496e899c4b842354ce9c2b1cd3a4..c3097a28a5026d884e0e96cd5ac46b1a5f6214cf 100644 (file)
 #endif
 #endif
 
-#if defined(OPEN_DATASYNC_FLAG)
+#if defined(PLATFORM_DEFAULT_SYNC_METHOD)
+#define DEFAULT_SYNC_METHOD_STR        PLATFORM_DEFAULT_SYNC_METHOD_STR
+#define DEFAULT_SYNC_METHOD            PLATFORM_DEFAULT_SYNC_METHOD
+#define DEFAULT_SYNC_FLAGBIT   PLATFORM_DEFAULT_SYNC_FLAGBIT
+#elif defined(OPEN_DATASYNC_FLAG)
 #define DEFAULT_SYNC_METHOD_STR "open_datasync"
 #define DEFAULT_SYNC_METHOD            SYNC_METHOD_OPEN
 #define DEFAULT_SYNC_FLAGBIT   OPEN_DATASYNC_FLAG
 #define DEFAULT_SYNC_METHOD_STR "fdatasync"
 #define DEFAULT_SYNC_METHOD            SYNC_METHOD_FDATASYNC
 #define DEFAULT_SYNC_FLAGBIT   0
-#elif defined(HAVE_FSYNC_WRITETHROUGH_ONLY)
-#define DEFAULT_SYNC_METHOD_STR "fsync_writethrough"
-#define DEFAULT_SYNC_METHOD            SYNC_METHOD_FSYNC_WRITETHROUGH
-#define DEFAULT_SYNC_FLAGBIT   0
 #else
 #define DEFAULT_SYNC_METHOD_STR "fsync"
 #define DEFAULT_SYNC_METHOD            SYNC_METHOD_FSYNC
index 3e3932b861ec64fa488f6358dea9a5b2567081de..87b6865ee6753144b982c4145ab0895bb8b395c3 100644 (file)
@@ -237,12 +237,13 @@ static void RemovePgTempFilesInDir(const char *tmpdirname);
 int
 pg_fsync(int fd)
 {
-#ifndef HAVE_FSYNC_WRITETHROUGH_ONLY
-       if (sync_method != SYNC_METHOD_FSYNC_WRITETHROUGH)
-               return pg_fsync_no_writethrough(fd);
+       /* #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 (sync_method == SYNC_METHOD_FSYNC_WRITETHROUGH)
+               return pg_fsync_writethrough(fd);
        else
 #endif
-               return pg_fsync_writethrough(fd);
+               return pg_fsync_no_writethrough(fd);
 }
 
 
index 29d7c078524fb86c4f5c4faf5887d185ff8d1c89..df62b67830cf764fee8282c3f2a4580e74f1f1ab 100644 (file)
 #wal_sync_method = fsync               # the default is the first option 
                                        # supported by the operating system:
                                        #   open_datasync
-                                       #   fdatasync
+                                       #   fdatasync (default on Linux)
                                        #   fsync
                                        #   fsync_writethrough
                                        #   open_sync
index 6feb22e1d5ce9fc4b7f5e91306908b17ea81fa35..562b5fbf04501a201e3b08491914e43a1bbb8532 100644 (file)
  * to have a kernel version test here.
  */
 #define HAVE_LINUX_EIDRM_BUG
+
+/*
+ * Set the default wal_sync_method to fdatasync.  With recent Linux versions,
+ * xlogdefs.h's normal rules will prefer open_datasync, which (a) doesn't
+ * perform better and (b) causes outright failures on ext4 data=journal
+ * filesystems, because those don't support O_DIRECT.
+ */
+#define PLATFORM_DEFAULT_SYNC_METHOD_STR "fdatasync"
+#define PLATFORM_DEFAULT_SYNC_METHOD   SYNC_METHOD_FDATASYNC
+#define PLATFORM_DEFAULT_SYNC_FLAGBIT  0
index 93d6e2a74c3945c7f60ae6cd2b78631acd4b3da8..cefafd0bd988588afc2d9eb69c0897e526cefd17 100644 (file)
 #define mkdir(a,b)     mkdir(a)
 
 
-#define HAVE_FSYNC_WRITETHROUGH
-#define HAVE_FSYNC_WRITETHROUGH_ONLY
 #define ftruncate(a,b) chsize(a,b)
+
+/* Windows doesn't have fsync() as such, use _commit() */
+#define fsync(fd) _commit(fd)
+
 /*
- *     Even though we don't support 'fsync' as a wal_sync_method,
- *     we do fsync() a few other places where _commit() is just fine.
+ * 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 fsync(fd) _commit(fd)
+#define HAVE_FSYNC_WRITETHROUGH
+#define FSYNC_WRITETHROUGH_IS_FSYNC
 
 #define USES_WINSOCK