diff --git a/src/tools/fsync/Makefile b/src/tools/fsync/Makefile new file mode 100644 index 0000000000..eb66aed25c --- /dev/null +++ b/src/tools/fsync/Makefile @@ -0,0 +1,22 @@ +# +# Makefile +# +# +TARGET = test_fsync +XFLAGS = +CFLAGS = -g -Wall +LIBS = + +$(TARGET) : test_fsync.o + $(CC) -o $(TARGET) $(XFLAGS) $(CFLAGS) test_fsync.o $(LIBS) + +test_fsync.o : test_fsync.c + $(CC) -c $(XFLAGS) $(CFLAGS) test_fsync.c + +clean: + rm -f *.o $(TARGET) log core + +install: + make clean + make CFLAGS=-O + install -s -o bin -g bin $(TARGET) /usr/local/bin diff --git a/src/tools/fsync/README b/src/tools/fsync/README new file mode 100644 index 0000000000..6da713afbf --- /dev/null +++ b/src/tools/fsync/README @@ -0,0 +1,7 @@ +This program tests fsync. If first times a simple read. Then, it times +an fsync that is part of a write, and one that is done on a newly opened +file. Third, it tests various fsync methods. + +The program writes to /var/tmp because /tmp is sometimes a memory file +system. + diff --git a/src/tools/fsync/test_fsync b/src/tools/fsync/test_fsync new file mode 100755 index 0000000000..2dc62f8df7 Binary files /dev/null and b/src/tools/fsync/test_fsync differ diff --git a/src/tools/fsync/test_fsync.c b/src/tools/fsync/test_fsync.c new file mode 100644 index 0000000000..cbeed45a65 --- /dev/null +++ b/src/tools/fsync/test_fsync.c @@ -0,0 +1,157 @@ +/* + * test_fsync.c + * tests if fsync can be done from another process than the original write + */ + +#include "../../include/pg_config.h" + +#include +#include +#include +#include +#include +#include + +/* O_SYNC and O_FSYNC are the same */ +#if defined(O_SYNC) +#define OPEN_SYNC_FLAG O_SYNC +#elif defined(O_FSYNC) +#define OPEN_SYNC_FLAG O_FSYNC +#endif + +#if defined(OPEN_SYNC_FLAG) +#if defined(O_DSYNC) && (O_DSYNC != OPEN_SYNC_FLAG) +#define OPEN_DATASYNC_FLAG O_DSYNC +#endif +#endif + +void die(char *str); +void print_elapse(struct timeval start_t, struct timeval elapse_t); + +int main(int argc, char *argv[]) +{ + struct timeval start_t; + struct timeval elapse_t; + int tmpfile; + char *strout = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + + printf("Simple write timing:\n"); + /* write only */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("write "); + print_elapse(start_t, elapse_t); + printf("\n\n"); + + printf("Compare fsync before and after write's close:\n"); + /* write, fsync, close */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + fsync(tmpfile); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("write, fsync, close "); + print_elapse(start_t, elapse_t); + printf("\n"); + + /* write, close, fsync */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + close(tmpfile); + /* reopen file */ + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + fsync(tmpfile); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("write, close, fsync "); + print_elapse(start_t, elapse_t); + printf("\n"); + + printf("\nTest file sync methods\n"); + +#ifdef OPEN_DATASYNC_FLAG + /* open_dsync, write */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT | O_DSYNC)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("open o_dsync, write "); + print_elapse(start_t, elapse_t); + printf("\n"); +#endif + + /* open_fsync, write */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT | OPEN_SYNC_FLAG)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("open o_fsync, write "); + print_elapse(start_t, elapse_t); + printf("\n"); + +#ifdef HAVE_FDATASYNC + /* write, fdatasync */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + fdatasync(tmpfile); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("write, fdatasync "); + print_elapse(start_t, elapse_t); + printf("\n"); +#endif + + /* write, fsync, close */ + gettimeofday(&start_t, NULL); + if ((tmpfile = open("/var/tmp/test_fsync.out", O_RDWR | O_CREAT)) == -1) + die("can't open /var/tmp/test_fsync.out"); + write(tmpfile, &strout, 200); + fsync(tmpfile); + close(tmpfile); + gettimeofday(&elapse_t, NULL); + unlink("/var/tmp/test_fsync.out"); + printf("write, fsync, "); + print_elapse(start_t, elapse_t); + printf("\n"); + + return 0; +} + +void print_elapse(struct timeval start_t, struct timeval elapse_t) +{ + if (elapse_t.tv_usec < start_t.tv_usec) + { + elapse_t.tv_sec--; + elapse_t.tv_usec += 1000000; + } + + printf("%ld.%06ld", (long) (elapse_t.tv_sec - start_t.tv_sec), + (long) (elapse_t.tv_usec - start_t.tv_usec)); +} + +void die(char *str) +{ + fprintf(stderr, "%s", str); + exit(1); +} diff --git a/src/tools/fsync/test_fsync.o b/src/tools/fsync/test_fsync.o new file mode 100644 index 0000000000..00ba396481 Binary files /dev/null and b/src/tools/fsync/test_fsync.o differ