Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9378701

Browse files
committed
Prioritize history files when archiving
At the end of recovery for the post-promotion process, a new history file is created followed by the last partial segment of the previous timeline. Based on the timing, the archiver would first try to archive the last partial segment and then the history file. This can delay the detection of a new timeline taken, particularly depending on the time it takes to transfer the last partial segment as it delays the moment the history file of the new timeline gets archived. This can cause promoted standbys to use the same timeline as one already taken depending on the circumstances if multiple instances look at archives at the same location. This commit changes the order of archiving so as history files are archived in priority over other file types, which reduces the likelihood of the same timeline being taken (still not reducing the window to zero), and it makes the archiver behave more consistently with the startup process doing its post-promotion business. Author: David Steele Reviewed-by: Michael Paquier, Kyotaro Horiguchi Discussion: https://postgr.es/m/929068cf-69e1-bba2-9dc0-e05986aed471@pgmasters.net Backpatch-through: 9.5
1 parent ffcd98c commit 9378701

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

src/backend/postmaster/pgarch.c

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -651,11 +651,12 @@ pgarch_archiveXlog(char *xlog)
651651
* 2) because the oldest ones will sooner become candidates for
652652
* recycling at time of checkpoint
653653
*
654-
* NOTE: the "oldest" comparison will presently consider all segments of
655-
* a timeline with a smaller ID to be older than all segments of a timeline
656-
* with a larger ID; the net result being that past timelines are given
657-
* higher priority for archiving. This seems okay, or at least not
658-
* obviously worth changing.
654+
* NOTE: the "oldest" comparison will consider any .history file to be older
655+
* than any other file except another .history file. Segments on a timeline
656+
* with a smaller ID will be older than all segments on a timeline with a
657+
* larger ID; the net result being that past timelines are given higher
658+
* priority for archiving. This seems okay, or at least not obviously worth
659+
* changing.
659660
*/
660661
static bool
661662
pgarch_readyXlog(char *xlog)
@@ -667,10 +668,10 @@ pgarch_readyXlog(char *xlog)
667668
* of calls, so....
668669
*/
669670
char XLogArchiveStatusDir[MAXPGPATH];
670-
char newxlog[MAX_XFN_CHARS + 6 + 1];
671671
DIR *rldir;
672672
struct dirent *rlde;
673673
bool found = false;
674+
bool historyFound = false;
674675

675676
snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
676677
rldir = AllocateDir(XLogArchiveStatusDir);
@@ -683,32 +684,51 @@ pgarch_readyXlog(char *xlog)
683684
while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
684685
{
685686
int basenamelen = (int) strlen(rlde->d_name) - 6;
687+
char basename[MAX_XFN_CHARS + 1];
688+
bool ishistory;
686689

687-
if (basenamelen >= MIN_XFN_CHARS &&
688-
basenamelen <= MAX_XFN_CHARS &&
689-
strspn(rlde->d_name, VALID_XFN_CHARS) >= basenamelen &&
690-
strcmp(rlde->d_name + basenamelen, ".ready") == 0)
690+
/* Ignore entries with unexpected number of characters */
691+
if (basenamelen < MIN_XFN_CHARS ||
692+
basenamelen > MAX_XFN_CHARS)
693+
continue;
694+
695+
/* Ignore entries with unexpected characters */
696+
if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
697+
continue;
698+
699+
/* Ignore anything not suffixed with .ready */
700+
if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
701+
continue;
702+
703+
/* Truncate off the .ready */
704+
memcpy(basename, rlde->d_name, basenamelen);
705+
basename[basenamelen] = '\0';
706+
707+
/* Is this a history file? */
708+
ishistory = IsTLHistoryFileName(basename);
709+
710+
/*
711+
* Consume the file to archive. History files have the highest
712+
* priority. If this is the first file or the first history file
713+
* ever, copy it. In the presence of a history file already chosen as
714+
* target, ignore all other files except history files which have been
715+
* generated for an older timeline than what is already chosen as
716+
* target to archive.
717+
*/
718+
if (!found || (ishistory && !historyFound))
691719
{
692-
if (!found)
693-
{
694-
strcpy(newxlog, rlde->d_name);
695-
found = true;
696-
}
697-
else
698-
{
699-
if (strcmp(rlde->d_name, newxlog) < 0)
700-
strcpy(newxlog, rlde->d_name);
701-
}
720+
strcpy(xlog, basename);
721+
found = true;
722+
historyFound = ishistory;
723+
}
724+
else if (ishistory || !historyFound)
725+
{
726+
if (strcmp(basename, xlog) < 0)
727+
strcpy(xlog, basename);
702728
}
703729
}
704730
FreeDir(rldir);
705731

706-
if (found)
707-
{
708-
/* truncate off the .ready */
709-
newxlog[strlen(newxlog) - 6] = '\0';
710-
strcpy(xlog, newxlog);
711-
}
712732
return found;
713733
}
714734

0 commit comments

Comments
 (0)