Skip to content

Commit 9430fb4

Browse files
committed
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
1 parent b24b2be commit 9430fb4

File tree

10 files changed

+86
-6
lines changed

10 files changed

+86
-6
lines changed

configure

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17132,6 +17132,12 @@ fi
1713217132
;;
1713317133
esac
1713417134

17135+
case " $LIBOBJS " in
17136+
*" fdatasync.$ac_objext "* ) ;;
17137+
*) LIBOBJS="$LIBOBJS fdatasync.$ac_objext"
17138+
;;
17139+
esac
17140+
1713517141
case " $LIBOBJS " in
1713617142
*" kill.$ac_objext "* ) ;;
1713717143
*) LIBOBJS="$LIBOBJS kill.$ac_objext"

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,7 @@ if test "$PORTNAME" = "win32"; then
19881988
AC_CHECK_FUNCS(_configthreadlocale)
19891989
AC_REPLACE_FUNCS(gettimeofday)
19901990
AC_LIBOBJ(dirmod)
1991+
AC_LIBOBJ(fdatasync)
19911992
AC_LIBOBJ(kill)
19921993
AC_LIBOBJ(open)
19931994
AC_LIBOBJ(system)

doc/src/sgml/wal.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@
108108
<literal>open_datasync</literal> (the default), write caching can be disabled
109109
by unchecking <literal>My Computer\Open\<replaceable>disk drive</replaceable>\Properties\Hardware\Properties\Policies\Enable write caching on the disk</literal>.
110110
Alternatively, set <varname>wal_sync_method</varname> to
111-
<literal>fsync</literal> or <literal>fsync_writethrough</literal>, which prevent
111+
<literal>fdatasync</literal> (NTFS only), <literal>fsync</literal> or
112+
<literal>fsync_writethrough</literal>, which prevent
112113
write caching.
113114
</para>
114115
</listitem>

src/include/c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ typedef union PGAlignedXLogBlock
12901290
* standard C library.
12911291
*/
12921292

1293-
#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC
1293+
#if !HAVE_DECL_FDATASYNC
12941294
extern int fdatasync(int fildes);
12951295
#endif
12961296

src/include/port/win32_port.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
#define HAVE_FSYNC_WRITETHROUGH
8484
#define FSYNC_WRITETHROUGH_IS_FSYNC
8585

86+
/*
87+
* We have a replacement for fdatasync() in src/port/fdatasync.c, which is
88+
* unconditionally used by MSVC and Mingw builds.
89+
*/
90+
#define HAVE_FDATASYNC
91+
8692
#define USES_WINSOCK
8793

8894
/*

src/include/port/win32ntdll.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@
2323
#include <ntstatus.h>
2424
#include <winternl.h>
2525

26-
typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void);
26+
#ifndef FLUSH_FLAGS_FILE_DATA_SYNC_ONLY
27+
#define FLUSH_FLAGS_FILE_DATA_SYNC_ONLY 0x4
28+
#endif
29+
30+
typedef NTSTATUS (__stdcall *RtlGetLastNtStatus_t) (void);
31+
typedef ULONG (__stdcall *RtlNtStatusToDosError_t) (NTSTATUS);
32+
typedef NTSTATUS (__stdcall *NtFlushBuffersFileEx_t) (HANDLE, ULONG, PVOID, ULONG, PIO_STATUS_BLOCK);
2733

2834
extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
35+
extern PGDLLIMPORT RtlNtStatusToDosError_t pg_RtlNtStatusToDosError;
36+
extern PGDLLIMPORT NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx;
2937

3038
extern int initialize_ntdll(void);
3139

src/port/fdatasync.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* fdatasync.c
4+
* Win32 fdatasync() replacement
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8+
*
9+
* src/port/fdatasync.c
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
14+
#define UMDF_USING_NTSTATUS
15+
16+
#ifdef FRONTEND
17+
#include "postgres_fe.h"
18+
#else
19+
#include "postgres.h"
20+
#endif
21+
22+
#include "port/win32ntdll.h"
23+
24+
int
25+
fdatasync(int fd)
26+
{
27+
IO_STATUS_BLOCK iosb;
28+
NTSTATUS status;
29+
HANDLE handle;
30+
31+
handle = (HANDLE) _get_osfhandle(fd);
32+
if (handle == INVALID_HANDLE_VALUE)
33+
{
34+
errno = EBADF;
35+
return -1;
36+
}
37+
38+
if (initialize_ntdll() < 0)
39+
return -1;
40+
41+
memset(&iosb, 0, sizeof(iosb));
42+
status = pg_NtFlushBuffersFileEx(handle,
43+
FLUSH_FLAGS_FILE_DATA_SYNC_ONLY,
44+
NULL,
45+
0,
46+
&iosb);
47+
48+
if (NT_SUCCESS(status))
49+
return 0;
50+
51+
_dosmaperr(pg_RtlNtStatusToDosError(status));
52+
return -1;
53+
}

src/port/win32ntdll.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "port/win32ntdll.h"
2121

2222
RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
23+
RtlNtStatusToDosError_t pg_RtlNtStatusToDosError;
24+
NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx;
2325

2426
typedef struct NtDllRoutine
2527
{
@@ -28,7 +30,9 @@ typedef struct NtDllRoutine
2830
} NtDllRoutine;
2931

3032
static const NtDllRoutine routines[] = {
31-
{"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus}
33+
{"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus},
34+
{"RtlNtStatusToDosError", (pg_funcptr_t *) &pg_RtlNtStatusToDosError},
35+
{"NtFlushBuffersFileEx", (pg_funcptr_t *) &pg_NtFlushBuffersFileEx}
3236
};
3337

3438
static bool initialized;

src/tools/msvc/Mkvcbuild.pm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ sub mkvcbuild
9999
$solution = CreateSolution($vsVersion, $config);
100100

101101
our @pgportfiles = qw(
102-
chklocale.c explicit_bzero.c fls.c getpeereid.c getrusage.c inet_aton.c
102+
chklocale.c explicit_bzero.c fls.c fdatasync.c
103+
getpeereid.c getrusage.c inet_aton.c
103104
getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
104105
snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
105106
dirent.c dlopen.c getopt.c getopt_long.c link.c

src/tools/msvc/Solution.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ sub GenerateFiles
257257
HAVE_EDITLINE_READLINE_H => undef,
258258
HAVE_EXECINFO_H => undef,
259259
HAVE_EXPLICIT_BZERO => undef,
260-
HAVE_FDATASYNC => undef,
260+
HAVE_FDATASYNC => 1,
261261
HAVE_FLS => undef,
262262
HAVE_FSEEKO => 1,
263263
HAVE_FUNCNAME__FUNC => undef,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy