mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Change contrib/pg_test_fsync to control tests in terms of seconds per
test, rather than a number of test cycles. Changes -o/cycles option to -s/seconds.
This commit is contained in:
parent
dc66f1c5f2
commit
0a8396e35e
@ -27,15 +27,31 @@
|
||||
#define NA_FORMAT "%18s"
|
||||
#define OPS_FORMAT "%9.3f ops/sec"
|
||||
|
||||
/* These are macros to avoid timing the function call overhead. */
|
||||
#define START_TIMER \
|
||||
do { \
|
||||
alarm_triggered = false; \
|
||||
alarm(secs_per_test); \
|
||||
gettimeofday(&start_t, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define STOP_TIMER \
|
||||
do { \
|
||||
gettimeofday(&stop_t, NULL); \
|
||||
print_elapse(start_t, stop_t, ops); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static const char *progname;
|
||||
|
||||
static int ops_per_test = 2000;
|
||||
static int secs_per_test = 2;
|
||||
static int needs_unlink = 0;
|
||||
static char full_buf[XLOG_SEG_SIZE],
|
||||
*buf,
|
||||
*filename = FSYNC_FILENAME;
|
||||
static struct timeval start_t,
|
||||
stop_t;
|
||||
static bool alarm_triggered = false;
|
||||
|
||||
|
||||
static void handle_args(int argc, char *argv[]);
|
||||
@ -46,12 +62,13 @@ 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);
|
||||
static void process_alarm(int sig);
|
||||
static void signal_cleanup(int sig);
|
||||
|
||||
#ifdef HAVE_FSYNC_WRITETHROUGH
|
||||
static int pg_fsync_writethrough(int fd);
|
||||
#endif
|
||||
static void print_elapse(struct timeval start_t, struct timeval stop_t);
|
||||
static void print_elapse(struct timeval start_t, struct timeval stop_t, int ops);
|
||||
static void die(const char *str);
|
||||
|
||||
|
||||
@ -65,6 +82,7 @@ main(int argc, char *argv[])
|
||||
/* Prevent leaving behind the test file */
|
||||
signal(SIGINT, signal_cleanup);
|
||||
signal(SIGTERM, signal_cleanup);
|
||||
signal(SIGALRM, process_alarm);
|
||||
#ifdef SIGHUP
|
||||
/* Not defined on win32 */
|
||||
signal(SIGHUP, signal_cleanup);
|
||||
@ -96,7 +114,7 @@ handle_args(int argc, char *argv[])
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
{"filename", required_argument, NULL, 'f'},
|
||||
{"ops-per-test", required_argument, NULL, 'o'},
|
||||
{"secs-per-test", required_argument, NULL, 's'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
int option; /* Command line option */
|
||||
@ -107,7 +125,7 @@ handle_args(int argc, char *argv[])
|
||||
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
|
||||
strcmp(argv[1], "-?") == 0)
|
||||
{
|
||||
printf("Usage: %s [-f FILENAME] [-o OPS-PER-TEST]\n", progname);
|
||||
printf("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n", progname);
|
||||
exit(0);
|
||||
}
|
||||
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
||||
@ -117,7 +135,7 @@ handle_args(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
while ((option = getopt_long(argc, argv, "f:o:",
|
||||
while ((option = getopt_long(argc, argv, "f:s:",
|
||||
long_options, &optindex)) != -1)
|
||||
{
|
||||
switch (option)
|
||||
@ -126,8 +144,8 @@ handle_args(int argc, char *argv[])
|
||||
filename = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
ops_per_test = atoi(optarg);
|
||||
case 's':
|
||||
secs_per_test = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -148,7 +166,7 @@ handle_args(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%d operations per test\n", ops_per_test);
|
||||
printf("%d seconds per test\n", secs_per_test);
|
||||
#if PG_O_DIRECT != 0
|
||||
printf("O_DIRECT supported on this platform for open_datasync and open_sync.\n");
|
||||
#else
|
||||
@ -220,8 +238,8 @@ test_sync(int writes_per_op)
|
||||
{
|
||||
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1)
|
||||
die("could not open output file");
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < writes_per_op; writes++)
|
||||
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
@ -229,9 +247,8 @@ test_sync(int writes_per_op)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
}
|
||||
#else
|
||||
printf(NA_FORMAT, "n/a\n");
|
||||
@ -246,8 +263,8 @@ test_sync(int writes_per_op)
|
||||
#ifdef HAVE_FDATASYNC
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < writes_per_op; writes++)
|
||||
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
@ -256,9 +273,8 @@ test_sync(int writes_per_op)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
#else
|
||||
printf(NA_FORMAT, "n/a\n");
|
||||
#endif
|
||||
@ -271,8 +287,8 @@ test_sync(int writes_per_op)
|
||||
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < writes_per_op; writes++)
|
||||
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
@ -282,9 +298,8 @@ test_sync(int writes_per_op)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
|
||||
/*
|
||||
* If fsync_writethrough is available, test as well
|
||||
@ -295,8 +310,8 @@ test_sync(int writes_per_op)
|
||||
#ifdef HAVE_FSYNC_WRITETHROUGH
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < writes_per_op; writes++)
|
||||
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
@ -306,9 +321,8 @@ test_sync(int writes_per_op)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
#else
|
||||
printf(NA_FORMAT, "n/a\n");
|
||||
#endif
|
||||
@ -327,8 +341,8 @@ test_sync(int writes_per_op)
|
||||
}
|
||||
else
|
||||
{
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < writes_per_op; writes++)
|
||||
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
|
||||
@ -336,9 +350,8 @@ test_sync(int writes_per_op)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
}
|
||||
#else
|
||||
printf(NA_FORMAT, "n/a\n");
|
||||
@ -385,8 +398,8 @@ test_open_sync(const char *msg, int writes_size)
|
||||
printf(NA_FORMAT, "n/a*\n");
|
||||
else
|
||||
{
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
for (writes = 0; writes < 16 / writes_size; writes++)
|
||||
if (write(tmpfile, buf, writes_size * 1024) !=
|
||||
@ -395,9 +408,8 @@ test_open_sync(const char *msg, int writes_size)
|
||||
if (lseek(tmpfile, 0, SEEK_SET) == -1)
|
||||
die("seek failed");
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
STOP_TIMER;
|
||||
close(tmpfile);
|
||||
print_elapse(start_t, stop_t);
|
||||
}
|
||||
#else
|
||||
printf(NA_FORMAT, "n/a\n");
|
||||
@ -427,8 +439,8 @@ test_file_descriptor_sync(void)
|
||||
printf(LABEL_FORMAT, "write, fsync, close");
|
||||
fflush(stdout);
|
||||
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
@ -446,8 +458,7 @@ test_file_descriptor_sync(void)
|
||||
die("could not open output file");
|
||||
close(tmpfile);
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
print_elapse(start_t, stop_t);
|
||||
STOP_TIMER;
|
||||
|
||||
/*
|
||||
* Now open, write, close, open again and fsync This simulates processes
|
||||
@ -456,8 +467,8 @@ test_file_descriptor_sync(void)
|
||||
printf(LABEL_FORMAT, "write, close, fsync");
|
||||
fflush(stdout);
|
||||
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
@ -471,9 +482,7 @@ test_file_descriptor_sync(void)
|
||||
die("fsync failed");
|
||||
close(tmpfile);
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
print_elapse(start_t, stop_t);
|
||||
|
||||
STOP_TIMER;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -489,8 +498,8 @@ test_non_sync(void)
|
||||
printf(LABEL_FORMAT, "write");
|
||||
fflush(stdout);
|
||||
|
||||
gettimeofday(&start_t, NULL);
|
||||
for (ops = 0; ops < ops_per_test; ops++)
|
||||
START_TIMER;
|
||||
for (ops = 0; alarm_triggered == false; ops++)
|
||||
{
|
||||
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
|
||||
die("could not open output file");
|
||||
@ -498,8 +507,7 @@ test_non_sync(void)
|
||||
die("write failed");
|
||||
close(tmpfile);
|
||||
}
|
||||
gettimeofday(&stop_t, NULL);
|
||||
print_elapse(start_t, stop_t);
|
||||
STOP_TIMER;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -533,15 +541,21 @@ pg_fsync_writethrough(int fd)
|
||||
* print out the writes per second for tests
|
||||
*/
|
||||
static void
|
||||
print_elapse(struct timeval start_t, struct timeval stop_t)
|
||||
print_elapse(struct timeval start_t, struct timeval stop_t, int ops)
|
||||
{
|
||||
double total_time = (stop_t.tv_sec - start_t.tv_sec) +
|
||||
(stop_t.tv_usec - start_t.tv_usec) * 0.000001;
|
||||
double per_second = ops_per_test / total_time;
|
||||
double per_second = ops / total_time;
|
||||
|
||||
printf(OPS_FORMAT "\n", per_second);
|
||||
}
|
||||
|
||||
static void
|
||||
process_alarm(int sig)
|
||||
{
|
||||
alarm_triggered = true;
|
||||
}
|
||||
|
||||
static void
|
||||
die(const char *str)
|
||||
{
|
||||
|
@ -47,13 +47,13 @@ pg_test_fsync [options]
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-o</option></term>
|
||||
<term><option>--ops-per-test</option></term>
|
||||
<term><option>-s</option></term>
|
||||
<term><option>--secs-per-test</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies the number of operations per test. The more operations
|
||||
Specifies the number of seconds for each test. The more time
|
||||
per test, the greater the test's accuracy, but the longer it takes
|
||||
to run. The default is 2000.
|
||||
to run. The default is 2 seconds.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
Loading…
Reference in New Issue
Block a user