mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Add wal_sync_method=fdatasync for Windows.
Windows 10 gained support for flushing NTFS files with fdatasync() semantics. The main advantage over open_datasync (in Windows API terms FILE_FLAG_WRITE_THROUGH) is that the latter does not flush SATA drive caches. The default setting is not changed, so users have to opt in to this. Discussion: https://postgr.es/m/CA%2BhUKGJZJVO%3DiX%2Beb-PXi2_XS9ZRqnn_4URh0NUQOwt6-_51xQ%40mail.gmail.com
This commit is contained in:
		
							parent
							
								
									b24b2be119
								
							
						
					
					
						commit
						9430fb407b
					
				
							
								
								
									
										6
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@ -17132,6 +17132,12 @@ fi
 | 
				
			|||||||
 ;;
 | 
					 ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case " $LIBOBJS " in
 | 
				
			||||||
 | 
					  *" fdatasync.$ac_objext "* ) ;;
 | 
				
			||||||
 | 
					  *) LIBOBJS="$LIBOBJS fdatasync.$ac_objext"
 | 
				
			||||||
 | 
					 ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case " $LIBOBJS " in
 | 
					  case " $LIBOBJS " in
 | 
				
			||||||
  *" kill.$ac_objext "* ) ;;
 | 
					  *" kill.$ac_objext "* ) ;;
 | 
				
			||||||
  *) LIBOBJS="$LIBOBJS kill.$ac_objext"
 | 
					  *) LIBOBJS="$LIBOBJS kill.$ac_objext"
 | 
				
			||||||
 | 
				
			|||||||
@ -1988,6 +1988,7 @@ if test "$PORTNAME" = "win32"; then
 | 
				
			|||||||
  AC_CHECK_FUNCS(_configthreadlocale)
 | 
					  AC_CHECK_FUNCS(_configthreadlocale)
 | 
				
			||||||
  AC_REPLACE_FUNCS(gettimeofday)
 | 
					  AC_REPLACE_FUNCS(gettimeofday)
 | 
				
			||||||
  AC_LIBOBJ(dirmod)
 | 
					  AC_LIBOBJ(dirmod)
 | 
				
			||||||
 | 
					  AC_LIBOBJ(fdatasync)
 | 
				
			||||||
  AC_LIBOBJ(kill)
 | 
					  AC_LIBOBJ(kill)
 | 
				
			||||||
  AC_LIBOBJ(open)
 | 
					  AC_LIBOBJ(open)
 | 
				
			||||||
  AC_LIBOBJ(system)
 | 
					  AC_LIBOBJ(system)
 | 
				
			||||||
 | 
				
			|||||||
@ -108,7 +108,8 @@
 | 
				
			|||||||
        <literal>open_datasync</literal> (the default), write caching can be disabled
 | 
					        <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>.
 | 
					        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
 | 
					        Alternatively, set <varname>wal_sync_method</varname> to
 | 
				
			||||||
        <literal>fsync</literal> or <literal>fsync_writethrough</literal>, which prevent
 | 
					        <literal>fdatasync</literal> (NTFS only), <literal>fsync</literal> or
 | 
				
			||||||
 | 
					        <literal>fsync_writethrough</literal>, which prevent
 | 
				
			||||||
        write caching.
 | 
					        write caching.
 | 
				
			||||||
      </para>
 | 
					      </para>
 | 
				
			||||||
    </listitem>
 | 
					    </listitem>
 | 
				
			||||||
 | 
				
			|||||||
@ -1290,7 +1290,7 @@ typedef union PGAlignedXLogBlock
 | 
				
			|||||||
 * standard C library.
 | 
					 * standard C library.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC
 | 
					#if !HAVE_DECL_FDATASYNC
 | 
				
			||||||
extern int	fdatasync(int fildes);
 | 
					extern int	fdatasync(int fildes);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -83,6 +83,12 @@
 | 
				
			|||||||
#define HAVE_FSYNC_WRITETHROUGH
 | 
					#define HAVE_FSYNC_WRITETHROUGH
 | 
				
			||||||
#define FSYNC_WRITETHROUGH_IS_FSYNC
 | 
					#define FSYNC_WRITETHROUGH_IS_FSYNC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * We have a replacement for fdatasync() in src/port/fdatasync.c, which is
 | 
				
			||||||
 | 
					 * unconditionally used by MSVC and Mingw builds.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define HAVE_FDATASYNC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USES_WINSOCK
 | 
					#define USES_WINSOCK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
				
			|||||||
@ -23,9 +23,17 @@
 | 
				
			|||||||
#include <ntstatus.h>
 | 
					#include <ntstatus.h>
 | 
				
			||||||
#include <winternl.h>
 | 
					#include <winternl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void);
 | 
					#ifndef FLUSH_FLAGS_FILE_DATA_SYNC_ONLY
 | 
				
			||||||
 | 
					#define FLUSH_FLAGS_FILE_DATA_SYNC_ONLY 0x4
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef NTSTATUS (__stdcall *RtlGetLastNtStatus_t) (void);
 | 
				
			||||||
 | 
					typedef ULONG (__stdcall *RtlNtStatusToDosError_t) (NTSTATUS);
 | 
				
			||||||
 | 
					typedef NTSTATUS (__stdcall *NtFlushBuffersFileEx_t) (HANDLE, ULONG, PVOID, ULONG, PIO_STATUS_BLOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
 | 
					extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
 | 
				
			||||||
 | 
					extern PGDLLIMPORT RtlNtStatusToDosError_t pg_RtlNtStatusToDosError;
 | 
				
			||||||
 | 
					extern PGDLLIMPORT NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int	initialize_ntdll(void);
 | 
					extern int	initialize_ntdll(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										53
									
								
								src/port/fdatasync.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/port/fdatasync.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					/*-------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * fdatasync.c
 | 
				
			||||||
 | 
					 *	   Win32 fdatasync() replacement
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * src/port/fdatasync.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UMDF_USING_NTSTATUS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef FRONTEND
 | 
				
			||||||
 | 
					#include "postgres_fe.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "postgres.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "port/win32ntdll.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					fdatasync(int fd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						IO_STATUS_BLOCK iosb;
 | 
				
			||||||
 | 
						NTSTATUS	status;
 | 
				
			||||||
 | 
						HANDLE		handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handle = (HANDLE) _get_osfhandle(fd);
 | 
				
			||||||
 | 
						if (handle == INVALID_HANDLE_VALUE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							errno = EBADF;
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (initialize_ntdll() < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&iosb, 0, sizeof(iosb));
 | 
				
			||||||
 | 
						status = pg_NtFlushBuffersFileEx(handle,
 | 
				
			||||||
 | 
														 FLUSH_FLAGS_FILE_DATA_SYNC_ONLY,
 | 
				
			||||||
 | 
														 NULL,
 | 
				
			||||||
 | 
														 0,
 | 
				
			||||||
 | 
														 &iosb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NT_SUCCESS(status))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_dosmaperr(pg_RtlNtStatusToDosError(status));
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -20,6 +20,8 @@
 | 
				
			|||||||
#include "port/win32ntdll.h"
 | 
					#include "port/win32ntdll.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
 | 
					RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
 | 
				
			||||||
 | 
					RtlNtStatusToDosError_t pg_RtlNtStatusToDosError;
 | 
				
			||||||
 | 
					NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct NtDllRoutine
 | 
					typedef struct NtDllRoutine
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -28,7 +30,9 @@ typedef struct NtDllRoutine
 | 
				
			|||||||
} NtDllRoutine;
 | 
					} NtDllRoutine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const NtDllRoutine routines[] = {
 | 
					static const NtDllRoutine routines[] = {
 | 
				
			||||||
	{"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus}
 | 
						{"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus},
 | 
				
			||||||
 | 
						{"RtlNtStatusToDosError", (pg_funcptr_t *) &pg_RtlNtStatusToDosError},
 | 
				
			||||||
 | 
						{"NtFlushBuffersFileEx", (pg_funcptr_t *) &pg_NtFlushBuffersFileEx}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool initialized;
 | 
					static bool initialized;
 | 
				
			||||||
 | 
				
			|||||||
@ -99,7 +99,8 @@ sub mkvcbuild
 | 
				
			|||||||
	$solution = CreateSolution($vsVersion, $config);
 | 
						$solution = CreateSolution($vsVersion, $config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	our @pgportfiles = qw(
 | 
						our @pgportfiles = qw(
 | 
				
			||||||
	  chklocale.c explicit_bzero.c fls.c getpeereid.c getrusage.c inet_aton.c
 | 
						  chklocale.c explicit_bzero.c fls.c fdatasync.c
 | 
				
			||||||
 | 
						  getpeereid.c getrusage.c inet_aton.c
 | 
				
			||||||
	  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 | 
						  getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
 | 
				
			||||||
	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 | 
						  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
 | 
				
			||||||
	  dirent.c dlopen.c getopt.c getopt_long.c link.c
 | 
						  dirent.c dlopen.c getopt.c getopt_long.c link.c
 | 
				
			||||||
 | 
				
			|||||||
@ -257,7 +257,7 @@ sub GenerateFiles
 | 
				
			|||||||
		HAVE_EDITLINE_READLINE_H                    => undef,
 | 
							HAVE_EDITLINE_READLINE_H                    => undef,
 | 
				
			||||||
		HAVE_EXECINFO_H                             => undef,
 | 
							HAVE_EXECINFO_H                             => undef,
 | 
				
			||||||
		HAVE_EXPLICIT_BZERO                         => undef,
 | 
							HAVE_EXPLICIT_BZERO                         => undef,
 | 
				
			||||||
		HAVE_FDATASYNC                              => undef,
 | 
							HAVE_FDATASYNC                              => 1,
 | 
				
			||||||
		HAVE_FLS                                    => undef,
 | 
							HAVE_FLS                                    => undef,
 | 
				
			||||||
		HAVE_FSEEKO                                 => 1,
 | 
							HAVE_FSEEKO                                 => 1,
 | 
				
			||||||
		HAVE_FUNCNAME__FUNC                         => undef,
 | 
							HAVE_FUNCNAME__FUNC                         => undef,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user