mirror of
https://github.com/postgres/postgres.git
synced 2025-11-28 11:44:57 +03:00
Make pg_receivexlog and pg_basebackup -X stream work across timeline switches.
This mirrors the changes done earlier to the server in standby mode. When receivelog reaches the end of a timeline, as reported by the server, it fetches the timeline history file of the next timeline, and restarts streaming from the new timeline by issuing a new START_STREAMING command. When pg_receivexlog crosses a timeline, it leaves the .partial suffix on the last segment on the old timeline. This helps you to tell apart a partial segment left in the directory because of a timeline switch, and a completed segment. If you just follow a single server, it won't make a difference, but it can be significant in more complicated scenarios where new WAL is still generated on the old timeline. This includes two small changes to the streaming replication protocol: First, when you reach the end of timeline while streaming, the server now sends the TLI of the next timeline in the server's history to the client. pg_receivexlog uses that as the next timeline, so that it doesn't need to parse the timeline history file like a standby server does. Second, when BASE_BACKUP command sends the begin and end WAL positions, it now also sends the timeline IDs corresponding the positions.
This commit is contained in:
@@ -545,22 +545,26 @@ tliOfPointInHistory(XLogRecPtr ptr, List *history)
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the point in history where we branched off the given timeline.
|
||||
* Returns InvalidXLogRecPtr if the timeline is current (= we have not
|
||||
* branched off from it), and throws an error if the timeline is not part of
|
||||
* this server's history.
|
||||
* Returns the point in history where we branched off the given timeline,
|
||||
* and the timeline we branched to (*nextTLI). Returns InvalidXLogRecPtr if
|
||||
* the timeline is current, ie. we have not branched off from it, and throws
|
||||
* an error if the timeline is not part of this server's history.
|
||||
*/
|
||||
XLogRecPtr
|
||||
tliSwitchPoint(TimeLineID tli, List *history)
|
||||
tliSwitchPoint(TimeLineID tli, List *history, TimeLineID *nextTLI)
|
||||
{
|
||||
ListCell *cell;
|
||||
|
||||
if (nextTLI)
|
||||
*nextTLI = 0;
|
||||
foreach (cell, history)
|
||||
{
|
||||
TimeLineHistoryEntry *tle = (TimeLineHistoryEntry *) lfirst(cell);
|
||||
|
||||
if (tle->tli == tli)
|
||||
return tle->end;
|
||||
if (nextTLI)
|
||||
*nextTLI = tle->tli;
|
||||
}
|
||||
|
||||
ereport(ERROR,
|
||||
|
||||
Reference in New Issue
Block a user