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  <br...@momjian.us>        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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to