1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03: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:
Bruce Momjian
2012-02-14 11:09:49 -05:00
parent dc66f1c5f2
commit 0a8396e35e
2 changed files with 65 additions and 51 deletions

View File

@ -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)
{