1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Force default wal_sync_method to be fdatasync on Linux.

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.
This commit is contained in:
Tom Lane
2010-12-08 20:01:29 -05:00
parent 5271c3cd80
commit 8b77981f89
6 changed files with 36 additions and 20 deletions

View File

@ -1404,12 +1404,12 @@ SET ENABLE_SEQSCAN TO OFF;
</listitem> </listitem>
<listitem> <listitem>
<para> <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> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <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> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -1419,10 +1419,11 @@ SET ENABLE_SEQSCAN TO OFF;
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para> <para>
The <literal>open_</>* options also use <literal>O_DIRECT</> if available.
Not all of these choices are available on all platforms. 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. by the platform, except that <literal>fdatasync</> is the default on
The <literal>open_</>* options also use <literal>O_DIRECT</> if available. Linux.
This parameter can only be set in the <filename>postgresql.conf</> This parameter can only be set in the <filename>postgresql.conf</>
file or on the server command line. file or on the server command line.
</para> </para>

View File

@ -93,7 +93,11 @@
#endif #endif
#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_STR "open_datasync"
#define DEFAULT_SYNC_METHOD SYNC_METHOD_OPEN #define DEFAULT_SYNC_METHOD SYNC_METHOD_OPEN
#define DEFAULT_SYNC_FLAGBIT OPEN_DATASYNC_FLAG #define DEFAULT_SYNC_FLAGBIT OPEN_DATASYNC_FLAG
@ -101,10 +105,6 @@
#define DEFAULT_SYNC_METHOD_STR "fdatasync" #define DEFAULT_SYNC_METHOD_STR "fdatasync"
#define DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC #define DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC
#define DEFAULT_SYNC_FLAGBIT 0 #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 #else
#define DEFAULT_SYNC_METHOD_STR "fsync" #define DEFAULT_SYNC_METHOD_STR "fsync"
#define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC #define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC

View File

@ -237,12 +237,13 @@ static void RemovePgTempFilesInDir(const char *tmpdirname);
int int
pg_fsync(int fd) pg_fsync(int fd)
{ {
#ifndef HAVE_FSYNC_WRITETHROUGH_ONLY /* #if is to skip the sync_method test if there's no need for it */
if (sync_method != SYNC_METHOD_FSYNC_WRITETHROUGH) #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
return pg_fsync_no_writethrough(fd); if (sync_method == SYNC_METHOD_FSYNC_WRITETHROUGH)
return pg_fsync_writethrough(fd);
else else
#endif #endif
return pg_fsync_writethrough(fd); return pg_fsync_no_writethrough(fd);
} }

View File

@ -153,7 +153,7 @@
#wal_sync_method = fsync # the default is the first option #wal_sync_method = fsync # the default is the first option
# supported by the operating system: # supported by the operating system:
# open_datasync # open_datasync
# fdatasync # fdatasync (default on Linux)
# fsync # fsync
# fsync_writethrough # fsync_writethrough
# open_sync # open_sync

View File

@ -12,3 +12,13 @@
* to have a kernel version test here. * to have a kernel version test here.
*/ */
#define HAVE_LINUX_EIDRM_BUG #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

View File

@ -25,15 +25,19 @@
/* Must be here to avoid conflicting with prototype in windows.h */ /* Must be here to avoid conflicting with prototype in windows.h */
#define mkdir(a,b) mkdir(a) #define mkdir(a,b) mkdir(a)
#define HAVE_FSYNC_WRITETHROUGH
#define HAVE_FSYNC_WRITETHROUGH_ONLY
#define ftruncate(a,b) chsize(a,b) #define ftruncate(a,b) chsize(a,b)
/*
* Even though we don't support 'fsync' as a wal_sync_method, /* Windows doesn't have fsync() as such, use _commit() */
* we do fsync() a few other places where _commit() is just fine.
*/
#define fsync(fd) _commit(fd) #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 #define USES_WINSOCK
/* defines for dynamic linking on Win32 platform */ /* defines for dynamic linking on Win32 platform */