]> granicus.if.org Git - postgresql/commitdiff
Retry opening new segments in pg_xlogdump --folllow
authorMagnus Hagander <magnus@hagander.net>
Fri, 30 Sep 2016 09:19:30 +0000 (11:19 +0200)
committerMagnus Hagander <magnus@hagander.net>
Fri, 30 Sep 2016 09:23:25 +0000 (11:23 +0200)
There is a small window between when the server closes out the existing
segment and the new one is created. Put a loop around the open call in
this case to make sure we wait for the new file to actually appear.

contrib/pg_xlogdump/pg_xlogdump.c

index 11fd7130552e8fb98636afec8bdfaf089fb0b27a..3206d85854a590f0f873f15f048e5f11dd1f380b 100644 (file)
@@ -231,6 +231,7 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id,
                if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo))
                {
                        char            fname[MAXFNAMELEN];
+                       int                     tries;
 
                        /* Switch to another logfile segment */
                        if (sendFile >= 0)
@@ -240,7 +241,30 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id,
 
                        XLogFileName(fname, timeline_id, sendSegNo);
 
-                       sendFile = fuzzy_open_file(directory, fname);
+                       /*
+                        * In follow mode there is a short period of time after the
+                        * server has written the end of the previous file before the
+                        * new file is available. So we loop for 5 seconds looking
+                        * for the file to appear before giving up.
+                        */
+                       for (tries = 0; tries < 10; tries++)
+                       {
+                               sendFile = fuzzy_open_file(directory, fname);
+                               if (sendFile >= 0)
+                                       break;
+                               if (errno == ENOENT)
+                               {
+                                       int                     save_errno = errno;
+
+                                       /* File not there yet, try again */
+                                       pg_usleep(500 * 1000);
+
+                                       errno = save_errno;
+                                       continue;
+                               }
+                               /* Any other error, fall through and fail */
+                               break;
+                       }
 
                        if (sendFile < 0)
                                fatal_error("could not find file \"%s\": %s",