mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04: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 | ||||
| 
 | ||||
|   case " $LIBOBJS " in | ||||
|   *" fdatasync.$ac_objext "* ) ;; | ||||
|   *) LIBOBJS="$LIBOBJS fdatasync.$ac_objext" | ||||
|  ;; | ||||
| esac | ||||
| 
 | ||||
|   case " $LIBOBJS " in | ||||
|   *" kill.$ac_objext "* ) ;; | ||||
|   *) LIBOBJS="$LIBOBJS kill.$ac_objext" | ||||
|  | ||||
| @ -1988,6 +1988,7 @@ if test "$PORTNAME" = "win32"; then | ||||
|   AC_CHECK_FUNCS(_configthreadlocale) | ||||
|   AC_REPLACE_FUNCS(gettimeofday) | ||||
|   AC_LIBOBJ(dirmod) | ||||
|   AC_LIBOBJ(fdatasync) | ||||
|   AC_LIBOBJ(kill) | ||||
|   AC_LIBOBJ(open) | ||||
|   AC_LIBOBJ(system) | ||||
|  | ||||
| @ -108,7 +108,8 @@ | ||||
|         <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>. | ||||
|         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. | ||||
|       </para> | ||||
|     </listitem> | ||||
|  | ||||
| @ -1290,7 +1290,7 @@ typedef union PGAlignedXLogBlock | ||||
|  * standard C library. | ||||
|  */ | ||||
| 
 | ||||
| #if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC | ||||
| #if !HAVE_DECL_FDATASYNC | ||||
| extern int	fdatasync(int fildes); | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -83,6 +83,12 @@ | ||||
| #define HAVE_FSYNC_WRITETHROUGH | ||||
| #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 | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -23,9 +23,17 @@ | ||||
| #include <ntstatus.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 RtlNtStatusToDosError_t pg_RtlNtStatusToDosError; | ||||
| extern PGDLLIMPORT NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx; | ||||
| 
 | ||||
| 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" | ||||
| 
 | ||||
| RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; | ||||
| RtlNtStatusToDosError_t pg_RtlNtStatusToDosError; | ||||
| NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx; | ||||
| 
 | ||||
| typedef struct NtDllRoutine | ||||
| { | ||||
| @ -28,7 +30,9 @@ typedef struct NtDllRoutine | ||||
| } NtDllRoutine; | ||||
| 
 | ||||
| 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; | ||||
|  | ||||
| @ -99,7 +99,8 @@ sub mkvcbuild | ||||
| 	$solution = CreateSolution($vsVersion, $config); | ||||
| 
 | ||||
| 	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 | ||||
| 	  snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c | ||||
| 	  dirent.c dlopen.c getopt.c getopt_long.c link.c | ||||
|  | ||||
| @ -257,7 +257,7 @@ sub GenerateFiles | ||||
| 		HAVE_EDITLINE_READLINE_H                    => undef, | ||||
| 		HAVE_EXECINFO_H                             => undef, | ||||
| 		HAVE_EXPLICIT_BZERO                         => undef, | ||||
| 		HAVE_FDATASYNC                              => undef, | ||||
| 		HAVE_FDATASYNC                              => 1, | ||||
| 		HAVE_FLS                                    => undef, | ||||
| 		HAVE_FSEEKO                                 => 1, | ||||
| 		HAVE_FUNCNAME__FUNC                         => undef, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user