]> granicus.if.org Git - postgresql/blob - src/tools/fsync/test_fsync.c
Add missing third argument to open().
[postgresql] / src / tools / fsync / test_fsync.c
1 /*
2  * $PostgreSQL: pgsql/src/tools/fsync/test_fsync.c,v 1.22 2009/05/08 14:06:27 momjian Exp $ 
3  *
4  *
5  *      test_fsync.c
6  *              test various fsync() methods
7  */
8
9 #include "postgres.h"
10
11 #include "access/xlog_internal.h"
12 #include "access/xlog.h"
13 #include "access/xlogdefs.h"
14
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <time.h>
21 #include <sys/time.h>
22 #include <unistd.h>
23 #include <string.h>
24
25
26 #ifdef WIN32
27 #define FSYNC_FILENAME  "./test_fsync.out"
28 #else
29 /* /tmp might be a memory file system */
30 #define FSYNC_FILENAME  "/var/tmp/test_fsync.out"
31 #endif
32
33 #define WRITE_SIZE      (16 * 1024)
34
35 void            die(char *str);
36 void            print_elapse(struct timeval start_t, struct timeval elapse_t);
37
38 int
39 main(int argc, char *argv[])
40 {
41         struct timeval start_t;
42         struct timeval elapse_t;
43         int                     tmpfile,
44                                 i,
45                                 loops = 1000;
46         char       *full_buf = (char *) malloc(XLOG_SEG_SIZE),
47                            *buf;
48         char       *filename = FSYNC_FILENAME;
49
50         if (argc > 2 && strcmp(argv[1], "-f") == 0)
51         {
52                 filename = argv[2];
53                 argv += 2;
54                 argc -= 2;
55         }
56
57         if (argc > 1)
58                 loops = atoi(argv[1]);
59
60         for (i = 0; i < XLOG_SEG_SIZE; i++)
61                 full_buf[i] = 'a';
62
63         if ((tmpfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, 0)) == -1)
64                 die("Cannot open output file.");
65         if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE)
66                 die("write failed");
67         /* fsync so later fsync's don't have to do it */
68         if (fsync(tmpfile) != 0)
69                 die("fsync failed");
70         close(tmpfile);
71
72         buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf);
73
74         printf("Simple write timing:\n");
75         /* write only */
76         gettimeofday(&start_t, NULL);
77         for (i = 0; i < loops; i++)
78         {
79                 if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
80                         die("Cannot open output file.");
81                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
82                         die("write failed");
83                 close(tmpfile);
84         }
85         gettimeofday(&elapse_t, NULL);
86         printf("\twrite                  ");
87         print_elapse(start_t, elapse_t);
88         printf("\n");
89
90         printf("\nCompare fsync times on write() and non-write() descriptor:\n");
91         printf("(If the times are similar, fsync() can sync data written\n on a different descriptor.)\n");
92
93         /* write, fsync, close */
94         gettimeofday(&start_t, NULL);
95         for (i = 0; i < loops; i++)
96         {
97                 if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
98                         die("Cannot open output file.");
99                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
100                         die("write failed");
101                 if (fsync(tmpfile) != 0)
102                         die("fsync failed");
103                 close(tmpfile);
104                 if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
105                         die("Cannot open output file.");
106                 /* do nothing but the open/close the tests are consistent. */
107                 close(tmpfile);
108         }
109         gettimeofday(&elapse_t, NULL);
110         printf("\twrite, fsync, close    ");
111         print_elapse(start_t, elapse_t);
112         printf("\n");
113
114         /* write, close, fsync */
115         gettimeofday(&start_t, NULL);
116         for (i = 0; i < loops; i++)
117         {
118                 if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
119                         die("Cannot open output file.");
120                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
121                         die("write failed");
122                 close(tmpfile);
123                 /* reopen file */
124                 if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
125                         die("Cannot open output file.");
126                 if (fsync(tmpfile) != 0)
127                         die("fsync failed");
128                 close(tmpfile);
129         }
130         gettimeofday(&elapse_t, NULL);
131         printf("\twrite, close, fsync    ");
132         print_elapse(start_t, elapse_t);
133         printf("\n");
134
135         printf("\nCompare one o_sync write to two:\n");
136
137 #ifdef OPEN_SYNC_FLAG
138         /* 16k o_sync write */
139         if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1)
140                 die("Cannot open output file.");
141         gettimeofday(&start_t, NULL);
142         for (i = 0; i < loops; i++)
143                 if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE)
144                         die("write failed");
145         gettimeofday(&elapse_t, NULL);
146         close(tmpfile);
147         printf("\tone 16k o_sync write   ");
148         print_elapse(start_t, elapse_t);
149         printf("\n");
150
151         /* 2*8k o_sync writes */
152         if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1)
153                 die("Cannot open output file.");
154         gettimeofday(&start_t, NULL);
155         for (i = 0; i < loops; i++)
156         {
157                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
158                         die("write failed");
159                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
160                         die("write failed");
161         }
162         gettimeofday(&elapse_t, NULL);
163         close(tmpfile);
164         printf("\ttwo 8k o_sync writes   ");
165         print_elapse(start_t, elapse_t);
166         printf("\n");
167
168         printf("\nCompare file sync methods with one 8k write:\n");
169 #else
170         printf("\t(o_sync unavailable)  ");
171 #endif
172         printf("\n");
173
174 #ifdef OPEN_DATASYNC_FLAG
175         /* open_dsync, write */
176         if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1)
177                 die("Cannot open output file.");
178         gettimeofday(&start_t, NULL);
179         for (i = 0; i < loops; i++)
180                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
181                         die("write failed");
182         gettimeofday(&elapse_t, NULL);
183         close(tmpfile);
184         printf("\topen o_dsync, write    ");
185         print_elapse(start_t, elapse_t);
186         printf("\n");
187 #ifdef OPEN_SYNC_FLAG
188         /* open_fsync, write */
189         if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1)
190                 die("Cannot open output file.");
191         gettimeofday(&start_t, NULL);
192         for (i = 0; i < loops; i++)
193                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
194                         die("write failed");
195         gettimeofday(&elapse_t, NULL);
196         close(tmpfile);
197         printf("\topen o_sync, write     ");
198         print_elapse(start_t, elapse_t);
199 #endif
200 #else
201         printf("\t(o_dsync unavailable)  ");
202 #endif
203         printf("\n");
204
205 #ifdef HAVE_FDATASYNC
206         /* write, fdatasync */
207         if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
208                 die("Cannot open output file.");
209         gettimeofday(&start_t, NULL);
210         for (i = 0; i < loops; i++)
211         {
212                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
213                         die("write failed");
214                 fdatasync(tmpfile);
215         }
216         gettimeofday(&elapse_t, NULL);
217         close(tmpfile);
218         printf("\twrite, fdatasync       ");
219         print_elapse(start_t, elapse_t);
220 #else
221         printf("\t(fdatasync unavailable)");
222 #endif
223         printf("\n");
224
225         /* write, fsync, close */
226         if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
227                 die("Cannot open output file.");
228         gettimeofday(&start_t, NULL);
229         for (i = 0; i < loops; i++)
230         {
231                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
232                         die("write failed");
233                 if (fsync(tmpfile) != 0)
234                         die("fsync failed");
235         }
236         gettimeofday(&elapse_t, NULL);
237         close(tmpfile);
238         printf("\twrite, fsync,          ");
239         print_elapse(start_t, elapse_t);
240         printf("\n");
241
242         printf("\nCompare file sync methods with 2 8k writes:\n");
243
244 #ifdef OPEN_DATASYNC_FLAG
245         /* open_dsync, write */
246         if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1)
247                 die("Cannot open output file.");
248         gettimeofday(&start_t, NULL);
249         for (i = 0; i < loops; i++)
250         {
251                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
252                         die("write failed");
253                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
254                         die("write failed");
255         }
256         gettimeofday(&elapse_t, NULL);
257         close(tmpfile);
258         printf("\topen o_dsync, write    ");
259         print_elapse(start_t, elapse_t);
260 #else
261         printf("\t(o_dsync unavailable)  ");
262 #endif
263         printf("\n");
264
265 #ifdef OPEN_SYNC_FLAG
266         /* open_fsync, write */
267         if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1)
268                 die("Cannot open output file.");
269         gettimeofday(&start_t, NULL);
270         for (i = 0; i < loops; i++)
271         {
272                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
273                         die("write failed");
274                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
275                         die("write failed");
276         }
277         gettimeofday(&elapse_t, NULL);
278         close(tmpfile);
279         printf("\topen o_sync, write     ");
280         print_elapse(start_t, elapse_t);
281         printf("\n");
282 #endif
283
284 #ifdef HAVE_FDATASYNC
285         /* write, fdatasync */
286         if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
287                 die("Cannot open output file.");
288         gettimeofday(&start_t, NULL);
289         for (i = 0; i < loops; i++)
290         {
291                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
292                         die("write failed");
293                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
294                         die("write failed");
295                 fdatasync(tmpfile);
296         }
297         gettimeofday(&elapse_t, NULL);
298         close(tmpfile);
299         printf("\twrite, fdatasync       ");
300         print_elapse(start_t, elapse_t);
301 #else
302         printf("\t(fdatasync unavailable)");
303 #endif
304         printf("\n");
305
306         /* write, fsync, close */
307         if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
308                 die("Cannot open output file.");
309         gettimeofday(&start_t, NULL);
310         for (i = 0; i < loops; i++)
311         {
312                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
313                         die("write failed");
314                 if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2)
315                         die("write failed");
316                 if (fsync(tmpfile) != 0)
317                         die("fsync failed");
318         }
319         gettimeofday(&elapse_t, NULL);
320         close(tmpfile);
321         printf("\twrite, fsync,          ");
322         print_elapse(start_t, elapse_t);
323         printf("\n");
324
325         free(full_buf);
326         unlink(filename);
327
328         return 0;
329 }
330
331 void
332 print_elapse(struct timeval start_t, struct timeval elapse_t)
333 {
334         if (elapse_t.tv_usec < start_t.tv_usec)
335         {
336                 elapse_t.tv_sec--;
337                 elapse_t.tv_usec += 1000000;
338         }
339
340         printf("%3ld.%06ld", (long) (elapse_t.tv_sec - start_t.tv_sec),
341                    (long) (elapse_t.tv_usec - start_t.tv_usec));
342 }
343
344 void
345 die(char *str)
346 {
347         fprintf(stderr, "%s\n", str);
348         exit(1);
349 }