- url="http://www.sun.com/bigadmin/content/submitted/format_utility.jsp">format
- -e>. (The Solaris
ZFS> file system is safe with
- disk write-cache enabled because it issues its own disk cache flush
- commands.) On
Windows> if wal_sync_method>
- is open_datasync> (the default), write caching is disabled
- by unchecking My Computer\Open\{select disk
- drive}\Properties\Hardware\Properties\Policies\Enable write caching on
- the disk>. Also on Windows, fsync> and
- fsync_writethrough> never do write caching. The
- fsync_writethrough> option can also be used to disable
- write caching on
MacOS X>.
-
-
- Many file systems that use write barriers (e.g.
ZFS>,
-
ext4>) internally use FLUSH CACHE EXT> or
- SYNCHRONIZE CACHE> commands to flush data to the platters on
- write-back-enabled drives. Unfortunately, such write barrier file
- systems behave suboptimally when combined with battery-backed unit
+ to have write-back caches that will not survive a power failure. Many
+ solid-state drives (SSD) also have volatile write-back caches.
+
+
+ These caches can typically be disabled; however, the method for doing
+ this varies by operating system and drive type:
+
+
+
+
+ On
Linux>, IDE drives can be queried using
+ hdparm -I; write caching is enabled if there is
+ a *> next to Write cache>. hdparm -W>
+ can be used to turn off write caching. SCSI drives can be queried
+ Use sdparm --get=WCE to check
+ whether the write cache is enabled and sdparm --clear=WCE>
+ to disable it.
+
+
+
+
+ On
FreeBSD>, IDE drives can be queried using
+ atacontrol, and SCSI drives using
+ sdparm.
+
+
+
+
+ On
Solaris>, the disk write cache is controlled by
+ (The Solaris
ZFS> file system is safe with disk write-cache
+ enabled because it issues its own disk cache flush commands.)
+
+
+
+
+ On
Windows>, if wal_sync_method> is
+ open_datasync> (the default), write caching can be disabled
+ by unchecking My Computer\Open\disk drive>\Properties\Hardware\Properties\Policies\Enable write caching on the disk>.
+ Alternatively, set wal_sync_method to
+ fsync> or fsync_writethrough>, which prevent
+ write caching.
+
+
+
+
+ On
Mac OS X, write caching can be prevented by
+ setting wal_sync_method> to fsync_writethrough>.
+
+
+
+
+ Recent SATA drives (those following
ATAPI-6> or later)
+ offer a drive cache flush command (FLUSH CACHE EXT>),
+ while SCSI drives have long supported a similar command
+ SYNCHRONIZE CACHE>. These commands are not directly
+ accessible to
PostgreSQL>, but some file systems
+ (e.g.,
ZFS>, ext4>) can use them to flush
+ data to the platters on write-back-enabled drives. Unfortunately, such
+ file systems behave suboptimally when combined with battery-backup unit
(
BBU>) disk controllers. In such setups, the synchronize
- command forces all data from the BBU to the disks, eliminating much
- of the benefit of the BBU. You can run the utility
+ command forces all data from the controller cache to the disks,
+ eliminating much of the benefit of the BBU. You can run the utility
src/tools/fsync> in the PostgreSQL source tree to see
if you are affected. If you are affected, the performance benefits
- of the BBU cache can be regained by turning off write barriers in
+ of the BBU can be regained by turning off write barriers in
the file system or reconfiguring the disk controller, if that is
an option. If write barriers are turned off, make sure the battery
- remains active; a faulty battery can potentially lead to data loss.
+ remains functional; a faulty battery can potentially lead to data loss.
Hopefully file system and disk controller designers will eventually
address this suboptimal behavior.
ensure data integrity. Avoid disk controllers that have non-battery-backed
write caches. At the drive level, disable write-back caching if the
drive cannot guarantee the data will be written before shutdown.
+ If you use SSDs, be aware that many of these do not honor cache flush
+ commands by default.
You can test for reliable I/O subsystem behavior using
url="http://brad.livejournal.com/2116715.html">diskchecker.pl.
operations themselves. Disk platters are divided into sectors,
commonly 512 bytes each. Every physical read or write operation
processes a whole sector.
- When a write request arrives at the drive, it might be for 512 bytes,
- 1024 bytes, or 8192 bytes, and the process of writing could fail due
+ When a write request arrives at the drive, it might be for some multiple
+ of 512 bytes (
PostgreSQL> typically writes 8192 bytes, or
+ 16 sectors, at a time), and the process of writing could fail due
to power loss at any time, meaning some of the 512-byte sectors were
- written, and others were not. To guard against such failures,
+ written while others were not. To guard against such failures,
PostgreSQL> periodically writes full page images to
permanent WAL storage before> modifying the actual page on
disk. By doing this, during crash recovery
PostgreSQL> can
- restore partially-written pages. If you have a battery-backed disk
+ restore partially-written pages from WAL. If you have a battery-backed disk
controller or file-system software that prevents partial page writes
- (e.g., ZFS), you can turn off this page imaging by turning off the
+ (e.g., ZFS), you can safely turn off this page imaging by turning off the
parameter.
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);
}
#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
#endif
#endif
-#if defined(OPEN_DATASYNC_FLAG)
+#if defined(PLATFORM_DEFAULT_SYNC_METHOD)
+#define DEFAULT_SYNC_METHOD PLATFORM_DEFAULT_SYNC_METHOD
+#elif defined(OPEN_DATASYNC_FLAG)
#define DEFAULT_SYNC_METHOD SYNC_METHOD_OPEN_DSYNC
#elif defined(HAVE_FDATASYNC)
#define DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC
-#elif defined(HAVE_FSYNC_WRITETHROUGH_ONLY)
-#define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC_WRITETHROUGH
#else
#define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC
#endif
* 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 SYNC_METHOD_FDATASYNC
/* Must be here to avoid conflicting with prototype in windows.h */
#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