2004-03-17 22:56:59 -05:00
|
|
|
/*
|
2011-01-21 19:27:25 -05:00
|
|
|
* pg_test_fsync.c
|
2011-01-15 11:54:43 -05:00
|
|
|
* tests all supported fsync() methods
|
2004-03-17 22:56:59 -05:00
|
|
|
*/
|
|
|
|
|
|
2011-01-22 15:01:26 -05:00
|
|
|
#include "postgres_fe.h"
|
2006-11-24 20:22:28 -05:00
|
|
|
|
2011-01-21 19:27:25 -05:00
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/time.h>
|
Avoid depending on non-POSIX behavior of fcntl(2).
The POSIX standard does not say that the success return value for
fcntl(F_SETFD) and fcntl(F_SETFL) is zero; it says only that it's not -1.
We had several calls that were making the stronger assumption. Adjust
them to test specifically for -1 for strict spec compliance.
The standard further leaves open the possibility that the O_NONBLOCK
flag bit is not the only active one in F_SETFL's argument. Formally,
therefore, one ought to get the current flags with F_GETFL and store
them back with only the O_NONBLOCK bit changed when trying to change
the nonblock state. In port/noblock.c, we were doing the full pushup
in pg_set_block but not in pg_set_noblock, which is just weird. Make
both of them do it properly, since they have little business making
any assumptions about the socket they're handed. The other places
where we're issuing F_SETFL are working with FDs we just got from
pipe(2), so it's reasonable to assume the FDs' properties are all
default, so I didn't bother adding F_GETFL steps there.
Also, while pg_set_block deserves some points for trying to do things
right, somebody had decided that it'd be even better to cast fcntl's
third argument to "long". Which is completely loony, because POSIX
clearly says the third argument for an F_SETFL call is "int".
Given the lack of field complaints, these missteps apparently are not
of significance on any common platforms. But they're still wrong,
so back-patch to all supported branches.
Discussion: https://postgr.es/m/30882.1492800880@sss.pgh.pa.us
2017-04-21 15:55:56 -04:00
|
|
|
#include <fcntl.h>
|
2011-01-21 19:27:25 -05:00
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
2011-12-09 15:05:48 -05:00
|
|
|
#include <signal.h>
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-17 09:35:51 -05:00
|
|
|
#include "getopt_long.h"
|
2007-02-14 00:00:40 -05:00
|
|
|
#include "access/xlogdefs.h"
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2011-01-21 19:27:25 -05:00
|
|
|
/*
|
2011-01-15 11:54:43 -05:00
|
|
|
* put the temp files in the local directory
|
2011-01-21 19:27:25 -05:00
|
|
|
* unless the user specifies otherwise
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
2011-01-21 19:27:25 -05:00
|
|
|
#define FSYNC_FILENAME "./pg_test_fsync.out"
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-25 22:18:24 -05:00
|
|
|
#define XLOG_BLCKSZ_K (XLOG_BLCKSZ / 1024)
|
2009-11-28 10:04:54 -05:00
|
|
|
|
2014-10-20 15:34:59 -04:00
|
|
|
#define LABEL_FORMAT " %-30s"
|
2017-08-25 11:49:05 -04:00
|
|
|
#define NA_FORMAT "%21s\n"
|
|
|
|
|
/* translator: maintain alignment with NA_FORMAT */
|
|
|
|
|
#define OPS_FORMAT gettext_noop("%13.3f ops/sec %6.0f usecs/op\n")
|
2012-10-09 03:15:23 -04:00
|
|
|
#define USECS_SEC 1000000
|
2011-01-15 11:54:43 -05:00
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
/* These are macros to avoid timing the function call overhead. */
|
2012-02-14 21:53:17 -05:00
|
|
|
#ifndef WIN32
|
2012-06-10 15:20:04 -04:00
|
|
|
#define START_TIMER \
|
2012-02-14 11:09:49 -05:00
|
|
|
do { \
|
|
|
|
|
alarm_triggered = false; \
|
|
|
|
|
alarm(secs_per_test); \
|
|
|
|
|
gettimeofday(&start_t, NULL); \
|
|
|
|
|
} while (0)
|
2012-02-14 21:53:17 -05:00
|
|
|
#else
|
2012-02-15 07:10:48 -05:00
|
|
|
/* WIN32 doesn't support alarm, so we create a thread and sleep there */
|
2012-06-10 15:20:04 -04:00
|
|
|
#define START_TIMER \
|
2012-02-14 21:53:17 -05:00
|
|
|
do { \
|
|
|
|
|
alarm_triggered = false; \
|
|
|
|
|
if (CreateThread(NULL, 0, process_alarm, NULL, 0, NULL) == \
|
|
|
|
|
INVALID_HANDLE_VALUE) \
|
|
|
|
|
{ \
|
2017-08-25 11:49:05 -04:00
|
|
|
fprintf(stderr, _("Could not create thread for alarm\n")); \
|
2012-02-14 21:53:17 -05:00
|
|
|
exit(1); \
|
|
|
|
|
} \
|
|
|
|
|
gettimeofday(&start_t, NULL); \
|
|
|
|
|
} while (0)
|
|
|
|
|
#endif
|
2012-02-14 11:09:49 -05:00
|
|
|
|
|
|
|
|
#define STOP_TIMER \
|
|
|
|
|
do { \
|
|
|
|
|
gettimeofday(&stop_t, NULL); \
|
|
|
|
|
print_elapse(start_t, stop_t, ops); \
|
|
|
|
|
} while (0)
|
2012-06-10 15:20:04 -04:00
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
|
2011-01-22 15:01:26 -05:00
|
|
|
static const char *progname;
|
|
|
|
|
|
2013-03-15 17:41:47 -04:00
|
|
|
static int secs_per_test = 5;
|
2011-12-09 15:05:48 -05:00
|
|
|
static int needs_unlink = 0;
|
2011-04-10 11:42:00 -04:00
|
|
|
static char full_buf[XLOG_SEG_SIZE],
|
|
|
|
|
*buf,
|
|
|
|
|
*filename = FSYNC_FILENAME;
|
|
|
|
|
static struct timeval start_t,
|
|
|
|
|
stop_t;
|
2012-02-14 11:09:49 -05:00
|
|
|
static bool alarm_triggered = false;
|
2011-04-10 11:42:00 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
static void handle_args(int argc, char *argv[]);
|
|
|
|
|
static void prepare_buf(void);
|
|
|
|
|
static void test_open(void);
|
|
|
|
|
static void test_non_sync(void);
|
|
|
|
|
static void test_sync(int writes_per_op);
|
|
|
|
|
static void test_open_syncs(void);
|
|
|
|
|
static void test_open_sync(const char *msg, int writes_size);
|
|
|
|
|
static void test_file_descriptor_sync(void);
|
2012-06-10 15:20:04 -04:00
|
|
|
|
2012-02-15 07:10:48 -05:00
|
|
|
#ifndef WIN32
|
2012-02-14 11:09:49 -05:00
|
|
|
static void process_alarm(int sig);
|
2012-02-15 07:10:48 -05:00
|
|
|
#else
|
|
|
|
|
static DWORD WINAPI process_alarm(LPVOID param);
|
|
|
|
|
#endif
|
2011-12-09 15:05:48 -05:00
|
|
|
static void signal_cleanup(int sig);
|
2011-04-10 11:42:00 -04:00
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
#ifdef HAVE_FSYNC_WRITETHROUGH
|
|
|
|
|
static int pg_fsync_writethrough(int fd);
|
|
|
|
|
#endif
|
2012-02-14 11:09:49 -05:00
|
|
|
static void print_elapse(struct timeval start_t, struct timeval stop_t, int ops);
|
2011-04-10 11:42:00 -04:00
|
|
|
static void die(const char *str);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2004-03-18 10:26:27 -05:00
|
|
|
int
|
|
|
|
|
main(int argc, char *argv[])
|
2004-03-17 22:56:59 -05:00
|
|
|
{
|
2016-10-14 12:00:00 -04:00
|
|
|
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_test_fsync"));
|
2011-01-22 15:01:26 -05:00
|
|
|
progname = get_progname(argv[0]);
|
|
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
handle_args(argc, argv);
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-12-09 15:05:48 -05:00
|
|
|
/* Prevent leaving behind the test file */
|
2013-03-17 16:09:47 -04:00
|
|
|
pqsignal(SIGINT, signal_cleanup);
|
|
|
|
|
pqsignal(SIGTERM, signal_cleanup);
|
2012-02-14 21:53:17 -05:00
|
|
|
#ifndef WIN32
|
2013-03-17 16:09:47 -04:00
|
|
|
pqsignal(SIGALRM, process_alarm);
|
2012-02-14 21:53:17 -05:00
|
|
|
#endif
|
2011-12-09 15:05:48 -05:00
|
|
|
#ifdef SIGHUP
|
|
|
|
|
/* Not defined on win32 */
|
2013-03-17 16:09:47 -04:00
|
|
|
pqsignal(SIGHUP, signal_cleanup);
|
2011-12-09 15:05:48 -05:00
|
|
|
#endif
|
|
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
prepare_buf();
|
|
|
|
|
|
|
|
|
|
test_open();
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-25 22:18:24 -05:00
|
|
|
/* Test using 1 XLOG_BLCKSZ write */
|
2011-01-15 14:42:12 -05:00
|
|
|
test_sync(1);
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-01-25 22:18:24 -05:00
|
|
|
/* Test using 2 XLOG_BLCKSZ writes */
|
2011-01-15 14:42:12 -05:00
|
|
|
test_sync(2);
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
test_open_syncs();
|
|
|
|
|
|
|
|
|
|
test_file_descriptor_sync();
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-18 15:53:20 -05:00
|
|
|
test_non_sync();
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
unlink(filename);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
handle_args(int argc, char *argv[])
|
|
|
|
|
{
|
2011-01-17 09:35:51 -05:00
|
|
|
static struct option long_options[] = {
|
|
|
|
|
{"filename", required_argument, NULL, 'f'},
|
2012-02-14 11:09:49 -05:00
|
|
|
{"secs-per-test", required_argument, NULL, 's'},
|
2011-01-17 09:35:51 -05:00
|
|
|
{NULL, 0, NULL, 0}
|
|
|
|
|
};
|
2012-11-30 14:49:55 -05:00
|
|
|
|
2011-01-17 09:35:51 -05:00
|
|
|
int option; /* Command line option */
|
|
|
|
|
int optindex = 0; /* used by getopt_long */
|
|
|
|
|
|
|
|
|
|
if (argc > 1)
|
2011-01-15 14:42:12 -05:00
|
|
|
{
|
2013-07-01 12:40:02 -04:00
|
|
|
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
|
2011-01-17 09:35:51 -05:00
|
|
|
{
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n"), progname);
|
2011-01-17 09:35:51 -05:00
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
|
|
|
|
{
|
2011-05-10 14:34:26 -04:00
|
|
|
puts("pg_test_fsync (PostgreSQL) " PG_VERSION);
|
2011-01-17 09:35:51 -05:00
|
|
|
exit(0);
|
|
|
|
|
}
|
2011-01-15 14:42:12 -05:00
|
|
|
}
|
2011-01-17 09:35:51 -05:00
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
while ((option = getopt_long(argc, argv, "f:s:",
|
2011-04-10 11:42:00 -04:00
|
|
|
long_options, &optindex)) != -1)
|
2004-03-18 14:54:00 -05:00
|
|
|
{
|
2011-01-17 09:35:51 -05:00
|
|
|
switch (option)
|
|
|
|
|
{
|
|
|
|
|
case 'f':
|
|
|
|
|
filename = strdup(optarg);
|
|
|
|
|
break;
|
|
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
case 's':
|
|
|
|
|
secs_per_test = atoi(optarg);
|
2011-01-17 09:35:51 -05:00
|
|
|
break;
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-17 09:35:51 -05:00
|
|
|
default:
|
2016-10-14 12:00:00 -04:00
|
|
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
|
2011-01-22 15:01:26 -05:00
|
|
|
progname);
|
2011-01-17 09:35:51 -05:00
|
|
|
exit(1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-03-18 14:54:00 -05:00
|
|
|
}
|
2004-08-29 01:07:03 -04:00
|
|
|
|
2011-01-22 15:01:26 -05:00
|
|
|
if (argc > optind)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr,
|
2016-10-14 12:00:00 -04:00
|
|
|
_("%s: too many command-line arguments (first is \"%s\")\n"),
|
2011-01-22 15:01:26 -05:00
|
|
|
progname, argv[optind]);
|
2016-10-14 12:00:00 -04:00
|
|
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
|
2011-01-22 15:01:26 -05:00
|
|
|
progname);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(ngettext("%d second per test\n",
|
|
|
|
|
"%d seconds per test\n",
|
|
|
|
|
secs_per_test),
|
|
|
|
|
secs_per_test);
|
2011-03-10 20:25:41 -05:00
|
|
|
#if PG_O_DIRECT != 0
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("O_DIRECT supported on this platform for open_datasync and open_sync.\n"));
|
2011-03-10 20:25:41 -05:00
|
|
|
#else
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("Direct I/O is not supported on this platform.\n"));
|
2011-03-10 20:25:41 -05:00
|
|
|
#endif
|
2011-01-15 14:42:12 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
prepare_buf(void)
|
|
|
|
|
{
|
|
|
|
|
int ops;
|
2004-08-29 01:07:03 -04:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
/* write random data into buffer */
|
|
|
|
|
for (ops = 0; ops < XLOG_SEG_SIZE; ops++)
|
|
|
|
|
full_buf[ops] = random();
|
|
|
|
|
|
2013-07-08 06:01:11 -04:00
|
|
|
buf = (char *) TYPEALIGN(XLOG_BLCKSZ, full_buf);
|
2011-01-15 14:42:12 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
test_open(void)
|
|
|
|
|
{
|
|
|
|
|
int tmpfile;
|
2004-03-18 14:54:00 -05:00
|
|
|
|
2011-01-21 19:27:25 -05:00
|
|
|
/*
|
|
|
|
|
* test if we can open the target file
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_CREAT | PG_BINARY, S_IRUSR | S_IWUSR)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2011-12-09 15:05:48 -05:00
|
|
|
needs_unlink = 1;
|
2006-11-24 20:22:28 -05:00
|
|
|
if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE)
|
|
|
|
|
die("write failed");
|
2011-01-15 14:42:12 -05:00
|
|
|
|
|
|
|
|
/* fsync now so that dirty buffers don't skew later tests */
|
2006-11-24 20:22:28 -05:00
|
|
|
if (fsync(tmpfile) != 0)
|
|
|
|
|
die("fsync failed");
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
close(tmpfile);
|
|
|
|
|
}
|
2006-11-24 20:22:28 -05:00
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
test_sync(int writes_per_op)
|
|
|
|
|
{
|
2011-04-10 11:42:00 -04:00
|
|
|
int tmpfile,
|
|
|
|
|
ops,
|
|
|
|
|
writes;
|
2011-01-15 18:27:10 -05:00
|
|
|
bool fs_warning = false;
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-15 14:42:12 -05:00
|
|
|
if (writes_per_op == 1)
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("\nCompare file sync methods using one %dkB write:\n"), XLOG_BLCKSZ_K);
|
2011-01-15 14:42:12 -05:00
|
|
|
else
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("\nCompare file sync methods using two %dkB writes:\n"), XLOG_BLCKSZ_K);
|
|
|
|
|
printf(_("(in wal_sync_method preference order, except fdatasync is Linux's default)\n"));
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
|
|
|
|
* Test open_datasync if available
|
|
|
|
|
*/
|
2011-03-10 20:25:41 -05:00
|
|
|
printf(LABEL_FORMAT, "open_datasync");
|
2010-07-13 13:00:50 -04:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2011-03-10 20:25:41 -05:00
|
|
|
#ifdef OPEN_DATASYNC_FLAG
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT | PG_BINARY, 0)) == -1)
|
2011-01-15 18:27:10 -05:00
|
|
|
{
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a*"));
|
2011-01-15 18:27:10 -05:00
|
|
|
fs_warning = true;
|
|
|
|
|
}
|
2011-01-15 11:54:43 -05:00
|
|
|
else
|
|
|
|
|
{
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2011-01-15 11:54:43 -05:00
|
|
|
{
|
2011-01-15 14:42:12 -05:00
|
|
|
for (writes = 0; writes < writes_per_op; writes++)
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2011-01-15 14:42:12 -05:00
|
|
|
die("write failed");
|
2011-01-15 11:54:43 -05:00
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2011-01-15 11:54:43 -05:00
|
|
|
close(tmpfile);
|
|
|
|
|
}
|
2009-11-28 10:04:54 -05:00
|
|
|
#else
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a"));
|
2009-11-28 10:04:54 -05:00
|
|
|
#endif
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
|
|
|
|
* Test fdatasync if available
|
|
|
|
|
*/
|
2011-01-18 15:53:20 -05:00
|
|
|
printf(LABEL_FORMAT, "fdatasync");
|
2010-07-13 13:00:50 -04:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2011-03-10 20:25:41 -05:00
|
|
|
#ifdef HAVE_FDATASYNC
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2009-09-21 16:20:56 -04:00
|
|
|
{
|
2011-01-15 14:42:12 -05:00
|
|
|
for (writes = 0; writes < writes_per_op; writes++)
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2011-01-15 14:42:12 -05:00
|
|
|
die("write failed");
|
2009-11-28 10:04:54 -05:00
|
|
|
fdatasync(tmpfile);
|
2009-09-21 16:20:56 -04:00
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2004-03-18 10:26:27 -05:00
|
|
|
close(tmpfile);
|
2009-11-28 10:04:54 -05:00
|
|
|
#else
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a"));
|
2009-11-28 10:04:54 -05:00
|
|
|
#endif
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
|
|
|
|
* Test fsync
|
|
|
|
|
*/
|
2011-01-18 15:53:20 -05:00
|
|
|
printf(LABEL_FORMAT, "fsync");
|
2010-07-13 13:00:50 -04:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2004-03-18 14:54:00 -05:00
|
|
|
{
|
2011-01-15 14:42:12 -05:00
|
|
|
for (writes = 0; writes < writes_per_op; writes++)
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2011-01-15 14:42:12 -05:00
|
|
|
die("write failed");
|
2009-11-28 10:04:54 -05:00
|
|
|
if (fsync(tmpfile) != 0)
|
|
|
|
|
die("fsync failed");
|
2009-09-21 16:20:56 -04:00
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
2004-03-18 14:54:00 -05:00
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2004-03-18 10:26:27 -05:00
|
|
|
close(tmpfile);
|
2011-01-21 19:27:25 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
|
|
|
|
* If fsync_writethrough is available, test as well
|
2011-01-21 19:27:25 -05:00
|
|
|
*/
|
2011-01-18 15:53:20 -05:00
|
|
|
printf(LABEL_FORMAT, "fsync_writethrough");
|
2011-01-15 11:54:43 -05:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2011-03-10 20:25:41 -05:00
|
|
|
#ifdef HAVE_FSYNC_WRITETHROUGH
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2011-01-15 11:54:43 -05:00
|
|
|
{
|
2011-01-15 14:42:12 -05:00
|
|
|
for (writes = 0; writes < writes_per_op; writes++)
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2011-01-15 14:42:12 -05:00
|
|
|
die("write failed");
|
2011-01-21 19:44:53 -05:00
|
|
|
if (pg_fsync_writethrough(tmpfile) != 0)
|
2011-01-15 11:54:43 -05:00
|
|
|
die("fsync failed");
|
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2011-01-15 11:54:43 -05:00
|
|
|
close(tmpfile);
|
|
|
|
|
#else
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a"));
|
2011-01-15 11:54:43 -05:00
|
|
|
#endif
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
2011-01-15 14:42:12 -05:00
|
|
|
* Test open_sync if available
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
2011-03-10 20:25:41 -05:00
|
|
|
printf(LABEL_FORMAT, "open_sync");
|
2010-07-13 13:00:50 -04:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2011-03-10 20:25:41 -05:00
|
|
|
#ifdef OPEN_SYNC_FLAG
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT | PG_BINARY, 0)) == -1)
|
2011-01-15 18:27:10 -05:00
|
|
|
{
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a*"));
|
2011-01-15 18:27:10 -05:00
|
|
|
fs_warning = true;
|
|
|
|
|
}
|
2011-01-15 14:42:12 -05:00
|
|
|
else
|
2011-01-15 11:54:43 -05:00
|
|
|
{
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2011-01-15 14:42:12 -05:00
|
|
|
{
|
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++)
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2014-05-06 12:12:18 -04:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This can generate write failures if the filesystem has
|
|
|
|
|
* a large block size, e.g. 4k, and there is no support
|
|
|
|
|
* for O_DIRECT writes smaller than the file system block
|
|
|
|
|
* size, e.g. XFS.
|
|
|
|
|
*/
|
2011-01-15 14:42:12 -05:00
|
|
|
die("write failed");
|
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2011-01-15 14:42:12 -05:00
|
|
|
close(tmpfile);
|
2011-01-15 11:54:43 -05:00
|
|
|
}
|
|
|
|
|
#else
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a"));
|
2011-01-15 18:40:10 -05:00
|
|
|
#endif
|
|
|
|
|
|
2011-01-15 18:27:10 -05:00
|
|
|
if (fs_warning)
|
|
|
|
|
{
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("* This file system and its mount options do not support direct\n"
|
|
|
|
|
" I/O, e.g. ext4 in journaled mode.\n"));
|
2011-01-15 18:27:10 -05:00
|
|
|
}
|
2011-01-15 14:42:12 -05:00
|
|
|
}
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
test_open_syncs(void)
|
|
|
|
|
{
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("\nCompare open_sync with different write sizes:\n"));
|
|
|
|
|
printf(_("(This is designed to compare the cost of writing 16kB in different write\n"
|
|
|
|
|
"open_sync sizes.)\n"));
|
|
|
|
|
|
|
|
|
|
test_open_sync(_(" 1 * 16kB open_sync write"), 16);
|
|
|
|
|
test_open_sync(_(" 2 * 8kB open_sync writes"), 8);
|
|
|
|
|
test_open_sync(_(" 4 * 4kB open_sync writes"), 4);
|
|
|
|
|
test_open_sync(_(" 8 * 2kB open_sync writes"), 2);
|
|
|
|
|
test_open_sync(_("16 * 1kB open_sync writes"), 1);
|
2011-01-18 15:53:20 -05:00
|
|
|
}
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-01-22 12:25:48 -05:00
|
|
|
/*
|
|
|
|
|
* Test open_sync with different size files
|
|
|
|
|
*/
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-18 15:53:20 -05:00
|
|
|
test_open_sync(const char *msg, int writes_size)
|
|
|
|
|
{
|
2011-04-19 13:01:51 -04:00
|
|
|
#ifdef OPEN_SYNC_FLAG
|
2011-04-10 11:42:00 -04:00
|
|
|
int tmpfile,
|
|
|
|
|
ops,
|
|
|
|
|
writes;
|
2011-04-19 13:01:51 -04:00
|
|
|
#endif
|
2004-03-18 10:26:27 -05:00
|
|
|
|
2011-03-10 20:25:41 -05:00
|
|
|
printf(LABEL_FORMAT, msg);
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
|
|
#ifdef OPEN_SYNC_FLAG
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT | PG_BINARY, 0)) == -1)
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a*"));
|
2011-01-15 19:40:49 -05:00
|
|
|
else
|
2004-03-18 14:54:00 -05:00
|
|
|
{
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2011-01-15 19:40:49 -05:00
|
|
|
{
|
2011-01-18 15:53:20 -05:00
|
|
|
for (writes = 0; writes < 16 / writes_size; writes++)
|
2011-01-24 19:42:32 -05:00
|
|
|
if (write(tmpfile, buf, writes_size * 1024) !=
|
|
|
|
|
writes_size * 1024)
|
2011-01-18 15:53:20 -05:00
|
|
|
die("write failed");
|
2011-01-15 19:40:49 -05:00
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
|
|
|
|
die("seek failed");
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2011-01-15 19:40:49 -05:00
|
|
|
close(tmpfile);
|
|
|
|
|
}
|
2009-11-28 10:04:54 -05:00
|
|
|
#else
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(NA_FORMAT, _("n/a"));
|
2006-10-13 10:19:29 -04:00
|
|
|
#endif
|
2011-01-15 14:42:12 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-15 14:42:12 -05:00
|
|
|
test_file_descriptor_sync(void)
|
|
|
|
|
{
|
2011-04-10 11:42:00 -04:00
|
|
|
int tmpfile,
|
|
|
|
|
ops;
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2009-11-28 10:04:54 -05:00
|
|
|
/*
|
2011-04-10 11:42:00 -04:00
|
|
|
* Test whether fsync can sync data written on a different descriptor for
|
|
|
|
|
* the same file. This checks the efficiency of multi-process fsyncs
|
|
|
|
|
* against the same file. Possibly this should be done with writethrough
|
|
|
|
|
* on platforms which support it.
|
2009-11-28 10:04:54 -05:00
|
|
|
*/
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("\nTest if fsync on non-write file descriptor is honored:\n"));
|
|
|
|
|
printf(_("(If the times are similar, fsync() can sync data written on a different\n"
|
|
|
|
|
"descriptor.)\n"));
|
2009-11-28 10:04:54 -05:00
|
|
|
|
2011-01-21 19:27:25 -05:00
|
|
|
/*
|
2011-04-10 11:42:00 -04:00
|
|
|
* first write, fsync and close, which is the normal behavior without
|
|
|
|
|
* multiple descriptors
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
2011-01-18 15:53:20 -05:00
|
|
|
printf(LABEL_FORMAT, "write, fsync, close");
|
2010-07-13 13:00:50 -04:00
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2004-03-18 14:54:00 -05:00
|
|
|
{
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2006-11-24 20:22:28 -05:00
|
|
|
die("write failed");
|
2009-11-28 10:04:54 -05:00
|
|
|
if (fsync(tmpfile) != 0)
|
|
|
|
|
die("fsync failed");
|
|
|
|
|
close(tmpfile);
|
2011-04-10 11:42:00 -04:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
2011-04-10 11:42:00 -04:00
|
|
|
* open and close the file again to be consistent with the following
|
|
|
|
|
* test
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2009-11-28 10:04:54 -05:00
|
|
|
close(tmpfile);
|
2004-03-18 14:54:00 -05:00
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2004-03-17 22:56:59 -05:00
|
|
|
|
2011-01-15 11:54:43 -05:00
|
|
|
/*
|
2011-04-10 11:42:00 -04:00
|
|
|
* Now open, write, close, open again and fsync This simulates processes
|
|
|
|
|
* fsyncing each other's writes.
|
2011-01-15 11:54:43 -05:00
|
|
|
*/
|
2011-01-21 19:27:25 -05:00
|
|
|
printf(LABEL_FORMAT, "write, close, fsync");
|
|
|
|
|
fflush(stdout);
|
2011-01-15 14:42:12 -05:00
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2004-03-18 14:54:00 -05:00
|
|
|
{
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2006-11-24 20:22:28 -05:00
|
|
|
die("write failed");
|
2009-11-28 10:04:54 -05:00
|
|
|
close(tmpfile);
|
|
|
|
|
/* reopen file */
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2006-11-24 20:22:28 -05:00
|
|
|
if (fsync(tmpfile) != 0)
|
|
|
|
|
die("fsync failed");
|
2009-11-28 10:04:54 -05:00
|
|
|
close(tmpfile);
|
2004-03-18 14:54:00 -05:00
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2004-03-17 22:56:59 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-18 15:53:20 -05:00
|
|
|
test_non_sync(void)
|
|
|
|
|
{
|
2011-04-10 11:42:00 -04:00
|
|
|
int tmpfile,
|
|
|
|
|
ops;
|
2011-01-18 15:53:20 -05:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test a simple write without fsync
|
|
|
|
|
*/
|
2016-10-14 12:00:00 -04:00
|
|
|
printf(_("\nNon-sync'ed %dkB writes:\n"), XLOG_BLCKSZ_K);
|
2011-01-18 15:53:20 -05:00
|
|
|
printf(LABEL_FORMAT, "write");
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
2012-02-14 11:09:49 -05:00
|
|
|
START_TIMER;
|
|
|
|
|
for (ops = 0; alarm_triggered == false; ops++)
|
2011-01-18 15:53:20 -05:00
|
|
|
{
|
Switch pg_test_fsync to use binary mode on Windows
pg_test_fsync has always opened files using the text mode on Windows, as
this is the default mode used if not enforced by _setmode().
This fixes a failure when running pg_test_fsync down to 12 because
O_DSYNC and the text mode are not able to work together nicely. We
fixed the handling of O_DSYNC in 12~ for the tool by switching to the
concurrent-safe version of fopen() in src/port/ with 0ba06e0. And
40cfe86, by enforcing the text mode for compatibility reasons if O_TEXT
or O_BINARY are not specified by the caller, broke pg_test_fsync. For
all versions, this avoids any translation overhead, and pg_test_fsync
should test binary writes, so it is a gain in all cases.
Note that O_DSYNC is still not handled correctly in ~11, leading to
pg_test_fsync to show insanely high numbers for open_datasync() (using
this property it is easy to notice that the binary mode is much
faster). This would require a backpatch of 0ba06e0 and 40cfe86, which
could potentially break existing applications, so this is left out.
There are no TAP tests for this tool yet, so I have checked all builds
manually using MSVC. We could invent a new option to run a single
transaction instead of using a duration of 1s to make the tests a
maximum short, but this is left as future work.
Thanks to Bruce Momjian for the discussion.
Reported-by: Jeff Janes
Author: Michael Paquier
Discussion: https://postgr.es/m/16526-279ded30a230d275@postgresql.org
Backpatch-through: 9.5
2020-07-16 02:53:04 -04:00
|
|
|
if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1)
|
2011-01-22 15:01:26 -05:00
|
|
|
die("could not open output file");
|
2011-01-24 20:07:05 -05:00
|
|
|
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
2011-01-18 15:53:20 -05:00
|
|
|
die("write failed");
|
|
|
|
|
close(tmpfile);
|
|
|
|
|
}
|
2012-02-14 11:09:49 -05:00
|
|
|
STOP_TIMER;
|
2011-01-18 15:53:20 -05:00
|
|
|
}
|
|
|
|
|
|
2011-12-09 15:05:48 -05:00
|
|
|
static void
|
|
|
|
|
signal_cleanup(int signum)
|
|
|
|
|
{
|
|
|
|
|
/* Delete the file if it exists. Ignore errors */
|
|
|
|
|
if (needs_unlink)
|
|
|
|
|
unlink(filename);
|
|
|
|
|
/* Finish incomplete line on stdout */
|
|
|
|
|
puts("");
|
|
|
|
|
exit(signum);
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
#ifdef HAVE_FSYNC_WRITETHROUGH
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
pg_fsync_writethrough(int fd)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
return _commit(fd);
|
|
|
|
|
#elif defined(F_FULLFSYNC)
|
|
|
|
|
return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
|
|
|
|
|
#else
|
|
|
|
|
errno = ENOSYS;
|
|
|
|
|
return -1;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-01-21 19:27:25 -05:00
|
|
|
/*
|
2011-01-15 11:54:43 -05:00
|
|
|
* print out the writes per second for tests
|
|
|
|
|
*/
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2012-02-14 11:09:49 -05:00
|
|
|
print_elapse(struct timeval start_t, struct timeval stop_t, int ops)
|
2004-03-17 22:56:59 -05:00
|
|
|
{
|
2010-07-06 15:19:02 -04:00
|
|
|
double total_time = (stop_t.tv_sec - start_t.tv_sec) +
|
|
|
|
|
(stop_t.tv_usec - start_t.tv_usec) * 0.000001;
|
2012-02-14 11:09:49 -05:00
|
|
|
double per_second = ops / total_time;
|
2012-10-09 03:15:23 -04:00
|
|
|
double avg_op_time_us = (total_time / ops) * USECS_SEC;
|
2010-07-06 15:19:02 -04:00
|
|
|
|
2017-08-25 11:49:05 -04:00
|
|
|
printf(_(OPS_FORMAT), per_second, avg_op_time_us);
|
2004-03-17 22:56:59 -05:00
|
|
|
}
|
|
|
|
|
|
2012-02-15 07:10:48 -05:00
|
|
|
#ifndef WIN32
|
2012-02-14 11:09:49 -05:00
|
|
|
static void
|
|
|
|
|
process_alarm(int sig)
|
|
|
|
|
{
|
|
|
|
|
alarm_triggered = true;
|
2012-02-15 07:10:48 -05:00
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
static DWORD WINAPI
|
|
|
|
|
process_alarm(LPVOID param)
|
|
|
|
|
{
|
|
|
|
|
/* WIN32 doesn't support alarm, so we create a thread and sleep here */
|
|
|
|
|
Sleep(secs_per_test * 1000);
|
|
|
|
|
alarm_triggered = true;
|
2012-02-14 21:53:17 -05:00
|
|
|
ExitThread(0);
|
2012-02-14 11:09:49 -05:00
|
|
|
}
|
2012-02-15 07:10:48 -05:00
|
|
|
#endif
|
2012-02-14 11:09:49 -05:00
|
|
|
|
2011-01-21 19:44:53 -05:00
|
|
|
static void
|
2011-01-22 15:01:26 -05:00
|
|
|
die(const char *str)
|
2004-03-17 22:56:59 -05:00
|
|
|
{
|
2016-10-14 12:00:00 -04:00
|
|
|
fprintf(stderr, _("%s: %s\n"), _(str), strerror(errno));
|
2004-03-17 22:56:59 -05:00
|
|
|
exit(1);
|
|
|
|
|
}
|