From 3d39244e6e7374febff59eba338f7a82f696a618 Mon Sep 17 00:00:00 2001
From: Magnus Hagander <magnus@hagander.net>
Date: Fri, 30 Sep 2016 11:19:30 +0200
Subject: [PATCH] Retry opening new segments in pg_xlogdump --folllow

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.
---
 src/bin/pg_xlogdump/pg_xlogdump.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/bin/pg_xlogdump/pg_xlogdump.c b/src/bin/pg_xlogdump/pg_xlogdump.c
index 02575eb1c57..9ad9321e1f9 100644
--- a/src/bin/pg_xlogdump/pg_xlogdump.c
+++ b/src/bin/pg_xlogdump/pg_xlogdump.c
@@ -249,6 +249,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)
@@ -258,7 +259,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",
-- 
GitLab