Given my concerns around exactly what is going on in the Windows code,
I'm now afraid to mess with an all-platforms change to fdatasync as the
preferred default; if we do that it should probably just be in HEAD not
the back branches.  So I've come around to the idea that Marti's
proposal of a PLATFORM_DEFAULT_SYNC_METHOD symbol is the best way.
(One reason for adopting that rather than some other way is that it
seems quite likely we'll end up needing it for Windows.)

I haven't touched the documentation yet, but attached is a proposed
code patch against HEAD.  This forces the default to fdatasync on Linux,
and makes some cosmetic cleanups around the HAVE_FSYNC_WRITETHROUGH_ONLY
confusion.

                        regards, tom lane

diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index fd5ec78..4f7dc39 100644
*** a/src/backend/storage/file/fd.c
--- b/src/backend/storage/file/fd.c
*************** static bool looks_like_temp_rel_name(con
*** 260,271 ****
  int
  pg_fsync(int fd)
  {
! #ifndef HAVE_FSYNC_WRITETHROUGH_ONLY
! 	if (sync_method != SYNC_METHOD_FSYNC_WRITETHROUGH)
! 		return pg_fsync_no_writethrough(fd);
  	else
  #endif
! 		return pg_fsync_writethrough(fd);
  }
  
  
--- 260,272 ----
  int
  pg_fsync(int 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_no_writethrough(fd);
  }
  
  
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 18b214e..072096d 100644
*** a/src/include/access/xlogdefs.h
--- b/src/include/access/xlogdefs.h
*************** typedef uint32 TimeLineID;
*** 123,134 ****
  #endif
  #endif
  
! #if 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
--- 123,134 ----
  #endif
  #endif
  
! #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
  #else
  #define DEFAULT_SYNC_METHOD		SYNC_METHOD_FSYNC
  #endif
diff --git a/src/include/port/linux.h b/src/include/port/linux.h
index b9498b2..bcaa42d 100644
*** a/src/include/port/linux.h
--- b/src/include/port/linux.h
***************
*** 12,14 ****
--- 12,22 ----
   * 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
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 3417ab5..9c2ae4d 100644
*** a/src/include/port/win32.h
--- b/src/include/port/win32.h
***************
*** 34,47 ****
  /* 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)
  /*
!  *	Even though we don't support 'fsync' as a wal_sync_method,
!  *	we do fsync() a few other places where _commit() is just fine.
   */
! #define fsync(fd) _commit(fd)
  
  #define USES_WINSOCK
  
--- 34,51 ----
  /* Must be here to avoid conflicting with prototype in windows.h */
  #define mkdir(a,b)	mkdir(a)
  
  #define ftruncate(a,b)	chsize(a,b)
+ 
+ /* 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
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to