aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam')
-rw-r--r--src/backend/access/transam/timeline.c22
-rw-r--r--src/backend/access/transam/xlog.c22
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;