struct dirent *dirent;
XLogSegNo high_segno = 0;
uint32 high_tli = 0;
+ bool high_ispartial = false;
dir = opendir(basedir);
if (dir == NULL)
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;
/*
}
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;
}
}
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);
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)
{
return false;
}
+ snprintf(path, sizeof(path), "%s/%s", basedir, histfname);
+
/*
* Write into a temp file name.
*/
/*
* 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"),