Retry opening new segments in pg_xlogdump --folllow
authorMagnus Hagander
Fri, 30 Sep 2016 09:19:30 +0000 (11:19 +0200)
committerMagnus Hagander
Fri, 30 Sep 2016 09:22:49 +0000 (11:22 +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 30a8634da8acfb31a987ba8db9efcce2db19cd0c..499c855785b20de269300258480cde7badf8e198 100644 (file)
@@ -232,6 +232,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)
@@ -241,7 +242,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",