Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2dbe890

Browse files
committed
Support direct I/O on macOS.
Macs don't understand O_DIRECT, but they can disable caching with aseparate fcntl() call. Extend the file opening functions in fd.c tohandle this for us if the caller passes in PG_O_DIRECT.For now, this affects only WAL data and even then only if you set: max_wal_senders=0 wal_level=minimalThis is not expected to be very useful on its own, but later proposedpatches will make greater use of direct I/O, and it'll be useful fortesting if developers on Macs can see the effects.Reviewed-by: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/CA%2BhUKG%2BADiyyHe0cun2wfT%2BSVnFVqNYPxoO6J9zcZkVO7%2BNGig%40mail.gmail.com
1 parentf157db8 commit2dbe890

File tree

4 files changed

+83
-19
lines changed

4 files changed

+83
-19
lines changed

‎src/backend/storage/file/fd.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,10 +1057,46 @@ BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
10571057
intfd;
10581058

10591059
tryAgain:
1060+
#ifdefPG_O_DIRECT_USE_F_NOCACHE
1061+
1062+
/*
1063+
* The value we defined to stand in for O_DIRECT when simulating it with
1064+
* F_NOCACHE had better not collide with any of the standard flags.
1065+
*/
1066+
StaticAssertStmt((PG_O_DIRECT&
1067+
(O_APPEND |
1068+
O_CLOEXEC |
1069+
O_CREAT |
1070+
O_DSYNC |
1071+
O_RDWR |
1072+
O_RDONLY |
1073+
O_SYNC |
1074+
O_TRUNC |
1075+
O_WRONLY))==0,
1076+
"PG_O_DIRECT value collides with standard flag");
1077+
fd=open(fileName,fileFlags& ~PG_O_DIRECT,fileMode);
1078+
#else
10601079
fd=open(fileName,fileFlags,fileMode);
1080+
#endif
10611081

10621082
if (fd >=0)
1083+
{
1084+
#ifdefPG_O_DIRECT_USE_F_NOCACHE
1085+
if (fileFlags&PG_O_DIRECT)
1086+
{
1087+
if (fcntl(fd,F_NOCACHE,1)<0)
1088+
{
1089+
intsave_errno=errno;
1090+
1091+
close(fd);
1092+
errno=save_errno;
1093+
return-1;
1094+
}
1095+
}
1096+
#endif
1097+
10631098
returnfd;/* success! */
1099+
}
10641100

10651101
if (errno==EMFILE||errno==ENFILE)
10661102
{

‎src/bin/pg_test_fsync/pg_test_fsync.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,10 @@ handle_args(int argc, char *argv[])
217217
"%u seconds per test\n",
218218
secs_per_test),
219219
secs_per_test);
220-
#ifPG_O_DIRECT!=0
220+
#ifdefined(O_DIRECT)
221221
printf(_("O_DIRECT supported on this platform for open_datasync and open_sync.\n"));
222+
#elif defined(F_NOCACHE)
223+
printf(_("F_NOCACHE supported on this platform for open_datasync and open_sync.\n"));
222224
#else
223225
printf(_("Direct I/O is not supported on this platform.\n"));
224226
#endif
@@ -258,6 +260,31 @@ test_open(void)
258260
close(tmpfile);
259261
}
260262

263+
staticint
264+
open_direct(constchar*path,intflags,mode_tmode)
265+
{
266+
intfd;
267+
268+
#ifdefO_DIRECT
269+
flags |=O_DIRECT;
270+
#endif
271+
272+
fd=open(path,flags,mode);
273+
274+
#if !defined(O_DIRECT)&& defined(F_NOCACHE)
275+
if (fd >=0&&fcntl(fd,F_NOCACHE,1)<0)
276+
{
277+
intsave_errno=errno;
278+
279+
close(fd);
280+
errno=save_errno;
281+
return-1;
282+
}
283+
#endif
284+
285+
returnfd;
286+
}
287+
261288
staticvoid
262289
test_sync(intwrites_per_op)
263290
{
@@ -279,7 +306,7 @@ test_sync(int writes_per_op)
279306
fflush(stdout);
280307

281308
#ifdefOPEN_DATASYNC_FLAG
282-
if ((tmpfile=open(filename,O_RDWR |O_DSYNC |PG_O_DIRECT |PG_BINARY,0))==-1)
309+
if ((tmpfile=open_direct(filename,O_RDWR |O_DSYNC |PG_BINARY,0))==-1)
283310
{
284311
printf(NA_FORMAT,_("n/a*"));
285312
fs_warning= true;
@@ -386,7 +413,7 @@ test_sync(int writes_per_op)
386413
fflush(stdout);
387414

388415
#ifdefOPEN_SYNC_FLAG
389-
if ((tmpfile=open(filename,O_RDWR |OPEN_SYNC_FLAG |PG_O_DIRECT |PG_BINARY,0))==-1)
416+
if ((tmpfile=open_direct(filename,O_RDWR |OPEN_SYNC_FLAG |PG_BINARY,0))==-1)
390417
{
391418
printf(NA_FORMAT,_("n/a*"));
392419
fs_warning= true;
@@ -454,7 +481,7 @@ test_open_sync(const char *msg, int writes_size)
454481
fflush(stdout);
455482

456483
#ifdefOPEN_SYNC_FLAG
457-
if ((tmpfile=open(filename,O_RDWR |OPEN_SYNC_FLAG |PG_O_DIRECT |PG_BINARY,0))==-1)
484+
if ((tmpfile=open_direct(filename,O_RDWR |OPEN_SYNC_FLAG |PG_BINARY,0))==-1)
458485
printf(NA_FORMAT,_("n/a*"));
459486
else
460487
{

‎src/include/access/xlogdefs.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,6 @@ typedef uint32 TimeLineID;
6464
*/
6565
typedefuint16RepOriginId;
6666

67-
/*
68-
*Because O_DIRECT bypasses the kernel buffers, and because we never
69-
*read those buffers except during crash recovery or if wal_level != minimal,
70-
*it is a win to use it in all cases where we sync on each write(). We could
71-
*allow O_DIRECT with fsync(), but it is unclear if fsync() could process
72-
*writes not buffered in the kernel. Also, O_DIRECT is never enough to force
73-
*data to the drives, it merely tries to bypass the kernel cache, so we still
74-
*need O_SYNC/O_DSYNC.
75-
*/
76-
#ifdefO_DIRECT
77-
#definePG_O_DIRECTO_DIRECT
78-
#else
79-
#definePG_O_DIRECT0
80-
#endif
81-
8267
/*
8368
* This chunk of hackery attempts to determine which file sync methods
8469
* are available on the current platform, and to choose an appropriate

‎src/include/storage/fd.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ extern intmax_safe_fds;
7979
#defineFILE_POSSIBLY_DELETED(err)((err) == ENOENT || (err) == EACCES)
8080
#endif
8181

82+
/*
83+
* O_DIRECT is not standard, but almost every Unix has it. We translate it
84+
* to the appropriate Windows flag in src/port/open.c. We simulate it with
85+
* fcntl(F_NOCACHE) on macOS inside fd.c's open() wrapper. We use the name
86+
* PG_O_DIRECT rather than defining O_DIRECT in that case (probably not a good
87+
* idea on a Unix).
88+
*/
89+
#if defined(O_DIRECT)
90+
#definePG_O_DIRECT O_DIRECT
91+
#elif defined(F_NOCACHE)
92+
#definePG_O_DIRECT 0x80000000
93+
#definePG_O_DIRECT_USE_F_NOCACHE
94+
#else
95+
#definePG_O_DIRECT 0
96+
#endif
97+
8298
/*
8399
* prototypes for functions in fd.c
84100
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp