diff options
Diffstat (limited to 'src/backend/access/transam')
-rw-r--r-- | src/backend/access/transam/timeline.c | 22 | ||||
-rw-r--r-- | src/backend/access/transam/xlog.c | 22 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c index ad4f3162c53..51b37ca8f8c 100644 --- a/src/backend/access/transam/timeline.c +++ b/src/backend/access/transam/timeline.c @@ -41,6 +41,28 @@ #include "storage/fd.h" /* + * Copies all timeline history files with id's between 'begin' and 'end' + * from archive to pg_xlog. + */ +void +restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end) +{ + char path[MAXPGPATH]; + char histfname[MAXFNAMELEN]; + TimeLineID tli; + + for (tli = begin; tli < end; tli++) + { + if (tli == 1) + continue; + + TLHistoryFileName(histfname, tli); + if (RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false)) + KeepFileRestoredFromArchive(path, histfname); + } +} + +/* * Try to read a timeline's history file. * * If successful, return the list of component TLIs (the given TLI followed by diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9ad92271795..d316c979265 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3276,8 +3276,8 @@ rescanLatestTimeLine(void) bool found; ListCell *cell; TimeLineID newtarget; + TimeLineID oldtarget = recoveryTargetTLI; TimeLineHistoryEntry *currentTle = NULL; - /* use volatile pointer to prevent code rearrangement */ newtarget = findNewestTimeLine(recoveryTargetTLI); if (newtarget == recoveryTargetTLI) @@ -3336,6 +3336,12 @@ rescanLatestTimeLine(void) list_free_deep(expectedTLEs); expectedTLEs = newExpectedTLEs; + /* + * As in StartupXLOG(), try to ensure we have all the history files + * between the old target and new target in pg_xlog. + */ + restoreTimeLineHistoryFiles(oldtarget + 1, newtarget); + ereport(LOG, (errmsg("new target timeline is %u", recoveryTargetTLI))); @@ -4993,6 +4999,20 @@ StartupXLOG(void) */ ThisTimeLineID = checkPoint.ThisTimeLineID; + /* + * Copy any missing timeline history files between 'now' and the + * recovery target timeline from archive to pg_xlog. While we don't need + * those files ourselves - the history file of the recovery target + * timeline covers all the previous timelines in the history too - a + * cascading standby server might be interested in them. Or, if you + * archive the WAL from this server to a different archive than the + * master, it'd be good for all the history files to get archived there + * after failover, so that you can use one of the old timelines as a + * PITR target. Timeline history files are small, so it's better to copy + * them unnecessarily than not copy them and regret later. + */ + restoreTimeLineHistoryFiles(ThisTimeLineID, recoveryTargetTLI); + lastFullPageWrites = checkPoint.fullPageWrites; RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; |