I have modified test_fsync to use test labels that match wal_sync_method
values, and and added more tests for open_sync with different sizes.
This should make the program easier for novices to understand. Here is
a test run for Ubuntu 11.04:
$ ./test_fsync
2000 operations per test
Compare file sync methods using one 8k write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
open_datasync (non-direct I/O)* 85.127 ops/sec
open_datasync (direct I/O) 87.119 ops/sec
fdatasync 81.006 ops/sec
fsync 82.621 ops/sec
fsync_writethrough n/a
open_sync (non-direct I/O)* 84.412 ops/sec
open_sync (direct I/O) 91.006 ops/sec
* This non-direct I/O mode is not used by Postgres.
Compare file sync methods using two 8k writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
open_datasync (non-direct I/O)* 42.721 ops/sec
open_datasync (direct I/O) 45.296 ops/sec
fdatasync 76.665 ops/sec
fsync 78.361 ops/sec
fsync_writethrough n/a
open_sync (non-direct I/O)* 42.311 ops/sec
open_sync (direct I/O) 45.247 ops/sec
* This non-direct I/O mode is not used by Postgres.
Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16k
in different write open_sync sizes.)
1 16k open_sync write 86.740 ops/sec
2 8k open_sync writes 44.709 ops/sec
4 4k open_sync writes 22.096 ops/sec
8 2k open_sync writes 10.856 ops/sec
16 1k open_sync writes 5.434 ops/sec
Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
write, fsync, close 86.802 ops/sec
write, close, fsync 85.766 ops/sec
Non-sync'ed 8k writes:
write 83.068 ops/sec
Applied patch attached.
--
Bruce Momjian <[email protected]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ It's impossible for everything to be true. +
diff --git a/src/tools/fsync/test_fsync.c b/src/tools/fsync/test_fsync.c
index b1cec74..9c829ba 100644
*** /tmp/pgdiff.3331/yCQf2a_test_fsync.c Tue Jan 18 15:06:39 2011
--- src/tools/fsync/test_fsync.c Tue Jan 18 14:43:58 2011
*************** void test_open(void);
*** 47,52 ****
--- 47,53 ----
void test_non_sync(void);
void test_sync(int writes_per_op);
void test_open_syncs(void);
+ void test_open_sync(const char *msg, int writes_size);
void test_file_descriptor_sync(void);
void print_elapse(struct timeval start_t, struct timeval stop_t);
void die(char *str);
*************** main(int argc, char *argv[])
*** 61,68 ****
test_open();
- test_non_sync();
-
/* Test using 1 8k write */
test_sync(1);
--- 62,67 ----
*************** main(int argc, char *argv[])
*** 73,78 ****
--- 72,79 ----
test_file_descriptor_sync();
+ test_non_sync();
+
unlink(filename);
return 0;
*************** handle_args(int argc, char *argv[])
*** 105,111 ****
}
while ((option = getopt_long(argc, argv, "f:o:",
! long_options, &optindex)) != -1)
{
switch (option)
{
--- 106,112 ----
}
while ((option = getopt_long(argc, argv, "f:o:",
! long_options, &optindex)) != -1)
{
switch (option)
{
*************** handle_args(int argc, char *argv[])
*** 126,132 ****
}
}
! printf("%d operations per test\n\n", ops_per_test);
}
void
--- 127,133 ----
}
}
! printf("%d operations per test\n", ops_per_test);
}
void
*************** test_open(void)
*** 162,201 ****
}
void
- test_non_sync(void)
- {
- int tmpfile, ops;
-
- /*
- * Test a simple write without fsync
- */
- printf("Simple non-sync'ed write:\n");
- printf(LABEL_FORMAT, "8k write");
- fflush(stdout);
-
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
- {
- if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
- die("Cannot open output file.");
- if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE)
- die("write failed");
- close(tmpfile);
- }
- gettimeofday(&stop_t, NULL);
- print_elapse(start_t, stop_t);
- }
-
- void
test_sync(int writes_per_op)
{
int tmpfile, ops, writes;
bool fs_warning = false;
if (writes_per_op == 1)
! printf("\nCompare file sync methods using one write:\n");
else
! printf("\nCompare file sync methods using two writes:\n");
printf("(in wal_sync_method preference order, except fdatasync\n");
printf("is Linux's default)\n");
--- 163,177 ----
}
void
test_sync(int writes_per_op)
{
int tmpfile, ops, writes;
bool fs_warning = false;
if (writes_per_op == 1)
! printf("\nCompare file sync methods using one 8k write:\n");
else
! printf("\nCompare file sync methods using two 8k writes:\n");
printf("(in wal_sync_method preference order, except fdatasync\n");
printf("is Linux's default)\n");
*************** test_sync(int writes_per_op)
*** 203,218 ****
* Test open_datasync if available
*/
#ifdef OPEN_DATASYNC_FLAG
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "open_datasync 8k write"
! #if PG_O_DIRECT != 0
! "*"
! #endif
! );
! else
! printf(LABEL_FORMAT, "2 open_datasync 8k writes"
#if PG_O_DIRECT != 0
! "*"
#endif
);
fflush(stdout);
--- 179,187 ----
* Test open_datasync if available
*/
#ifdef OPEN_DATASYNC_FLAG
! printf(LABEL_FORMAT, "open_datasync"
#if PG_O_DIRECT != 0
! " (non-direct I/O)*"
#endif
);
fflush(stdout);
*************** test_sync(int writes_per_op)
*** 243,252 ****
}
else
{
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "open_datasync 8k direct I/O write");
! else
! printf(LABEL_FORMAT, "2 open_datasync 8k direct I/O writes");
fflush(stdout);
gettimeofday(&start_t, NULL);
--- 212,218 ----
}
else
{
! printf(LABEL_FORMAT, "open_datasync (direct I/O)");
fflush(stdout);
gettimeofday(&start_t, NULL);
*************** test_sync(int writes_per_op)
*** 262,269 ****
close(tmpfile);
print_elapse(start_t, stop_t);
}
- #else
- printf(NA_FORMAT, "o_direct", "n/a\n");
#endif
#else
--- 228,233 ----
*************** test_sync(int writes_per_op)
*** 274,283 ****
* Test fdatasync if available
*/
#ifdef HAVE_FDATASYNC
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "8k write, fdatasync");
! else
! printf(LABEL_FORMAT, "8k write, 8k write, fdatasync");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
--- 238,244 ----
* Test fdatasync if available
*/
#ifdef HAVE_FDATASYNC
! printf(LABEL_FORMAT, "fdatasync");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
*************** test_sync(int writes_per_op)
*** 302,311 ****
/*
* Test fsync
*/
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "8k write, fsync");
! else
! printf(LABEL_FORMAT, "8k write, 8k write, fsync");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
--- 263,269 ----
/*
* Test fsync
*/
! printf(LABEL_FORMAT, "fsync");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
*************** test_sync(int writes_per_op)
*** 329,338 ****
* If fsync_writethrough is available, test as well
*/
#ifdef HAVE_FSYNC_WRITETHROUGH
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "8k write, fsync_writethrough");
! else
! printf(LABEL_FORMAT, "8k write, 8k write, fsync_writethrough");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
--- 287,293 ----
* If fsync_writethrough is available, test as well
*/
#ifdef HAVE_FSYNC_WRITETHROUGH
! printf(LABEL_FORMAT, "fsync_writethrough");
fflush(stdout);
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
*************** test_sync(int writes_per_op)
*** 359,374 ****
* Test open_sync if available
*/
#ifdef OPEN_SYNC_FLAG
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "open_sync 8k write"
! #if PG_O_DIRECT != 0
! "*"
! #endif
! );
! else
! printf(LABEL_FORMAT, "2 open_sync 8k writes"
#if PG_O_DIRECT != 0
! "*"
#endif
);
fflush(stdout);
--- 314,322 ----
* Test open_sync if available
*/
#ifdef OPEN_SYNC_FLAG
! printf(LABEL_FORMAT, "open_sync"
#if PG_O_DIRECT != 0
! " (non-direct I/O)*"
#endif
);
fflush(stdout);
*************** test_sync(int writes_per_op)
*** 399,408 ****
}
else
{
! if (writes_per_op == 1)
! printf(LABEL_FORMAT, "open_sync 8k direct I/O write");
! else
! printf(LABEL_FORMAT, "2 open_sync 8k direct I/O writes");
fflush(stdout);
gettimeofday(&start_t, NULL);
--- 347,353 ----
}
else
{
! printf(LABEL_FORMAT, "open_sync (direct I/O)");
fflush(stdout);
gettimeofday(&start_t, NULL);
*************** test_sync(int writes_per_op)
*** 418,425 ****
close(tmpfile);
print_elapse(start_t, stop_t);
}
- #else
- printf(NA_FORMAT, "o_direct", "n/a\n");
#endif
#else
--- 363,368 ----
*************** test_sync(int writes_per_op)
*** 428,434 ****
#if defined(OPEN_DATASYNC_FLAG) || defined(OPEN_SYNC_FLAG)
if (PG_O_DIRECT != 0)
! printf("* This non-direct I/O option is not used by Postgres.\n");
#endif
if (fs_warning)
--- 371,377 ----
#if defined(OPEN_DATASYNC_FLAG) || defined(OPEN_SYNC_FLAG)
if (PG_O_DIRECT != 0)
! printf("* This non-direct I/O mode is not used by Postgres.\n");
#endif
if (fs_warning)
*************** test_sync(int writes_per_op)
*** 441,454 ****
void
test_open_syncs(void)
{
! int tmpfile, ops;
! /*
! * Compare 1 to 2 writes
! */
! printf("\nCompare open_sync with different sizes:\n");
! printf("(This is designed to compare the cost of one large\n");
! printf("sync'ed write and two smaller sync'ed writes.)\n");
/*
* Test open_sync with different size files
--- 384,405 ----
void
test_open_syncs(void)
{
! printf("\nCompare open_sync with different write sizes:\n");
! printf("(This is designed to compare the cost of writing 16k\n");
! printf("in different write open_sync sizes.)\n");
! test_open_sync(" 1 16k open_sync write", 16);
! test_open_sync(" 2 8k open_sync writes", 8);
! test_open_sync(" 4 4k open_sync writes", 4);
! test_open_sync(" 8 2k open_sync writes", 2);
! test_open_sync("16 1k open_sync writes", 1);
! }
!
!
! void
! test_open_sync(const char *msg, int writes_size)
! {
! int tmpfile, ops, writes;
/*
* Test open_sync with different size files
*************** test_open_syncs(void)
*** 458,471 ****
printf(NA_FORMAT, "o_direct", "n/a**\n");
else
{
! printf(LABEL_FORMAT, "open_sync 16k write");
fflush(stdout);
gettimeofday(&start_t, NULL);
for (ops = 0; ops < ops_per_test; ops++)
{
! if (write(tmpfile, buf, WRITE_SIZE * 2) != WRITE_SIZE * 2)
! die("write failed");
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
--- 409,423 ----
printf(NA_FORMAT, "o_direct", "n/a**\n");
else
{
! printf(LABEL_FORMAT, msg);
fflush(stdout);
gettimeofday(&start_t, NULL);
for (ops = 0; ops < ops_per_test; ops++)
{
! for (writes = 0; writes < 16 / writes_size; writes++)
! if (write(tmpfile, buf, writes_size) != writes_size)
! die("write failed");
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
*************** test_open_syncs(void)
*** 474,500 ****
print_elapse(start_t, stop_t);
}
- if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT, 0)) == -1)
- printf(NA_FORMAT, "o_direct", "n/a**\n");
- else
- {
- printf(LABEL_FORMAT, "2 open_sync 8k writes");
- fflush(stdout);
-
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
- {
- if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE)
- die("write failed");
- if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE)
- die("write failed");
- if (lseek(tmpfile, 0, SEEK_SET) == -1)
- die("seek failed");
- }
- gettimeofday(&stop_t, NULL);
- close(tmpfile);
- print_elapse(start_t, stop_t);
- }
#else
printf(NA_FORMAT, "open_sync", "n/a\n");
#endif
--- 426,431 ----
*************** test_file_descriptor_sync(void)
*** 520,526 ****
* first write, fsync and close, which is the
* normal behavior without multiple descriptors
*/
! printf(LABEL_FORMAT, "8k write, fsync, close");
fflush(stdout);
gettimeofday(&start_t, NULL);
--- 451,457 ----
* first write, fsync and close, which is the
* normal behavior without multiple descriptors
*/
! printf(LABEL_FORMAT, "write, fsync, close");
fflush(stdout);
gettimeofday(&start_t, NULL);
*************** test_file_descriptor_sync(void)
*** 549,555 ****
* This simulates processes fsyncing each other's
* writes.
*/
! printf(LABEL_FORMAT, "8k write, close, fsync");
fflush(stdout);
gettimeofday(&start_t, NULL);
--- 480,486 ----
* This simulates processes fsyncing each other's
* writes.
*/
! printf(LABEL_FORMAT, "write, close, fsync");
fflush(stdout);
gettimeofday(&start_t, NULL);
*************** test_file_descriptor_sync(void)
*** 572,577 ****
--- 503,533 ----
}
+ void
+ test_non_sync(void)
+ {
+ int tmpfile, ops;
+
+ /*
+ * Test a simple write without fsync
+ */
+ printf("\nNon-sync'ed 8k writes:\n");
+ printf(LABEL_FORMAT, "write");
+ fflush(stdout);
+
+ gettimeofday(&start_t, NULL);
+ for (ops = 0; ops < ops_per_test; ops++)
+ {
+ if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
+ die("Cannot open output file.");
+ if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE)
+ die("write failed");
+ close(tmpfile);
+ }
+ gettimeofday(&stop_t, NULL);
+ print_elapse(start_t, stop_t);
+ }
+
/*
* print out the writes per second for tests
*/
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers