aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_test_fsync
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2021-07-19 08:52:00 +1200
committerThomas Munro <tmunro@postgresql.org>2021-07-19 11:01:01 +1200
commit2dbe8905711ba09a2214b6e835f8f0c2c4981cb3 (patch)
tree775e44cb05c4dfa8f12e68eb388f04e9aa252c96 /src/bin/pg_test_fsync
parentf157db862225a7bfe041ca3f7b73e913e2a8d8d6 (diff)
downloadpostgresql-2dbe8905711ba09a2214b6e835f8f0c2c4981cb3.tar.gz
postgresql-2dbe8905711ba09a2214b6e835f8f0c2c4981cb3.zip
Support direct I/O on macOS.
Macs don't understand O_DIRECT, but they can disable caching with a separate fcntl() call. Extend the file opening functions in fd.c to handle 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=minimal This is not expected to be very useful on its own, but later proposed patches will make greater use of direct I/O, and it'll be useful for testing 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
Diffstat (limited to 'src/bin/pg_test_fsync')
-rw-r--r--src/bin/pg_test_fsync/pg_test_fsync.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 78dab5096c6..fef31844fa0 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -217,8 +217,10 @@ handle_args(int argc, char *argv[])
"%u seconds per test\n",
secs_per_test),
secs_per_test);
-#if PG_O_DIRECT != 0
+#if defined(O_DIRECT)
printf(_("O_DIRECT supported on this platform for open_datasync and open_sync.\n"));
+#elif defined(F_NOCACHE)
+ printf(_("F_NOCACHE supported on this platform for open_datasync and open_sync.\n"));
#else
printf(_("Direct I/O is not supported on this platform.\n"));
#endif
@@ -258,6 +260,31 @@ test_open(void)
close(tmpfile);
}
+static int
+open_direct(const char *path, int flags, mode_t mode)
+{
+ int fd;
+
+#ifdef O_DIRECT
+ flags |= O_DIRECT;
+#endif
+
+ fd = open(path, flags, mode);
+
+#if !defined(O_DIRECT) && defined(F_NOCACHE)
+ if (fd >= 0 && fcntl(fd, F_NOCACHE, 1) < 0)
+ {
+ int save_errno = errno;
+
+ close(fd);
+ errno = save_errno;
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
static void
test_sync(int writes_per_op)
{
@@ -279,7 +306,7 @@ test_sync(int writes_per_op)
fflush(stdout);
#ifdef OPEN_DATASYNC_FLAG
- if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT | PG_BINARY, 0)) == -1)
+ if ((tmpfile = open_direct(filename, O_RDWR | O_DSYNC | PG_BINARY, 0)) == -1)
{
printf(NA_FORMAT, _("n/a*"));
fs_warning = true;
@@ -386,7 +413,7 @@ test_sync(int writes_per_op)
fflush(stdout);
#ifdef OPEN_SYNC_FLAG
- if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT | PG_BINARY, 0)) == -1)
+ if ((tmpfile = open_direct(filename, O_RDWR | OPEN_SYNC_FLAG | PG_BINARY, 0)) == -1)
{
printf(NA_FORMAT, _("n/a*"));
fs_warning = true;
@@ -454,7 +481,7 @@ test_open_sync(const char *msg, int writes_size)
fflush(stdout);
#ifdef OPEN_SYNC_FLAG
- if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT | PG_BINARY, 0)) == -1)
+ if ((tmpfile = open_direct(filename, O_RDWR | OPEN_SYNC_FLAG | PG_BINARY, 0)) == -1)
printf(NA_FORMAT, _("n/a*"));
else
{