aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_basebackup/pg_receivexlog.c74
-rw-r--r--src/bin/pg_basebackup/receivelog.c7
2 files changed, 52 insertions, 29 deletions
diff --git a/src/bin/pg_basebackup/pg_receivexlog.c b/src/bin/pg_basebackup/pg_receivexlog.c
index 787a3951bda..031ec1aa97c 100644
--- a/src/bin/pg_basebackup/pg_receivexlog.c
+++ b/src/bin/pg_basebackup/pg_receivexlog.c
@@ -121,6 +121,7 @@ FindStreamingStart(uint32 *tli)
struct dirent *dirent;
XLogSegNo high_segno = 0;
uint32 high_tli = 0;
+ bool high_ispartial = false;
dir = opendir(basedir);
if (dir == NULL)
@@ -132,20 +133,32 @@ FindStreamingStart(uint32 *tli)
while ((dirent = readdir(dir)) != NULL)
{
- char fullpath[MAXPGPATH];
- struct stat statbuf;
uint32 tli;
unsigned int log,
seg;
XLogSegNo segno;
+ bool ispartial;
/*
* Check if the filename looks like an xlog file, or a .partial file.
* Xlog files are always 24 characters, and .partial files are 32
* characters.
*/
- if (strlen(dirent->d_name) != 24 ||
- strspn(dirent->d_name, "0123456789ABCDEF") != 24)
+ if (strlen(dirent->d_name) == 24)
+ {
+ if (strspn(dirent->d_name, "0123456789ABCDEF") != 24)
+ continue;
+ ispartial = false;
+ }
+ else if (strlen(dirent->d_name) == 32)
+ {
+ if (strspn(dirent->d_name, "0123456789ABCDEF") != 24)
+ continue;
+ if (strcmp(&dirent->d_name[24], ".partial") != 0)
+ continue;
+ ispartial = true;
+ }
+ else
continue;
/*
@@ -160,31 +173,40 @@ FindStreamingStart(uint32 *tli)
}
segno = ((uint64) log) << 32 | seg;
- /* Check if this is a completed segment or not */
- snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
- if (stat(fullpath, &statbuf) != 0)
+ /*
+ * Check that the segment has the right size, if it's supposed to be
+ * completed.
+ */
+ if (!ispartial)
{
- fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
- progname, fullpath, strerror(errno));
- disconnect_and_exit(1);
- }
+ struct stat statbuf;
+ char fullpath[MAXPGPATH];
- if (statbuf.st_size == XLOG_SEG_SIZE)
- {
- /* Completed segment */
- if (segno > high_segno || (segno == high_segno && tli > high_tli))
+ snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
+ if (stat(fullpath, &statbuf) != 0)
+ {
+ fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
+ progname, fullpath, strerror(errno));
+ disconnect_and_exit(1);
+ }
+
+ if (statbuf.st_size != XLOG_SEG_SIZE)
{
- high_segno = segno;
- high_tli = tli;
+ fprintf(stderr,
+ _("%s: segment file \"%s\" has incorrect size %d, skipping\n"),
+ progname, dirent->d_name, (int) statbuf.st_size);
continue;
}
}
- else
+
+ /* Looks like a valid segment. Remember that we saw it. */
+ if ((segno > high_segno) ||
+ (segno == high_segno && tli > high_tli) ||
+ (segno == high_segno && tli == high_tli && high_ispartial && !ispartial))
{
- fprintf(stderr,
- _("%s: segment file \"%s\" has incorrect size %d, skipping\n"),
- progname, dirent->d_name, (int) statbuf.st_size);
- continue;
+ high_segno = segno;
+ high_tli = tli;
+ high_ispartial = ispartial;
}
}
@@ -195,10 +217,12 @@ FindStreamingStart(uint32 *tli)
XLogRecPtr high_ptr;
/*
- * Move the starting pointer to the start of the next segment, since
- * the highest one we've seen was completed.
+ * Move the starting pointer to the start of the next segment, if
+ * the highest one we saw was completed. Otherwise start streaming
+ * from the beginning of the .partial segment.
*/
- high_segno++;
+ if (!high_ispartial)
+ high_segno++;
XLogSegNoOffsetToRecPtr(high_segno, 0, high_ptr);
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index d56a4d71ea2..02643eaea94 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -166,8 +166,7 @@ close_walfile(char *basedir, char *partial_suffix)
walfile = -1;
/*
- * Rename the .partial file only if we've completed writing the whole
- * segment or segment_complete is true.
+ * If we finished writing a .partial file, rename it into place.
*/
if (currpos == XLOG_SEG_SIZE && partial_suffix)
{
@@ -306,6 +305,8 @@ writeTimeLineHistoryFile(char *basedir, TimeLineID tli, char *filename, char *co
return false;
}
+ snprintf(path, sizeof(path), "%s/%s", basedir, histfname);
+
/*
* Write into a temp file name.
*/
@@ -356,8 +357,6 @@ writeTimeLineHistoryFile(char *basedir, TimeLineID tli, char *filename, char *co
/*
* Now move the completed history file into place with its final name.
*/
-
- snprintf(path, sizeof(path), "%s/%s", basedir, histfname);
if (rename(tmppath, path) < 0)
{
fprintf(stderr, _("%s: could not rename file \"%s\" to \"%s\": %s\n"),