test_fsync label adjustments - Mailing list pgsql-hackers

From Bruce Momjian
Subject test_fsync label adjustments
Date
Msg-id 201101182055.p0IKtCX10332@momjian.us
Whole thread Raw
Responses Re: test_fsync label adjustments  ("A.M." <agentm@themactionfaction.com>)
Re: test_fsync label adjustments  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
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  <bruce@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
   */

pgsql-hackers by date:

Previous
From: "Kevin Grittner"
Date:
Subject: Re: SSI patch version 12
Next
From: Bruce Momjian
Date:
Subject: Re: ToDo List Item - System Table Index Clustering