mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Teach xlogreader to follow timeline switches
Uses page-based mechanism to ensure we’re using the correct timeline. Tests are included to exercise the functionality using a cold disk-level copy of the master that's started up as a replica with slots intact, but the intended use of the functionality is with later features. Craig Ringer, reviewed by Simon Riggs and Andres Freund
This commit is contained in:
@@ -235,11 +235,14 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
|
||||
rsinfo->setResult = p->tupstore;
|
||||
rsinfo->setDesc = p->tupdesc;
|
||||
|
||||
/* compute the current end-of-wal */
|
||||
/*
|
||||
* Compute the current end-of-wal and maintain ThisTimeLineID.
|
||||
* RecoveryInProgress() will update ThisTimeLineID on promotion.
|
||||
*/
|
||||
if (!RecoveryInProgress())
|
||||
end_of_wal = GetFlushRecPtr();
|
||||
else
|
||||
end_of_wal = GetXLogReplayRecPtr(NULL);
|
||||
end_of_wal = GetXLogReplayRecPtr(&ThisTimeLineID);
|
||||
|
||||
ReplicationSlotAcquire(NameStr(*name));
|
||||
|
||||
@@ -280,6 +283,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
|
||||
/* invalidate non-timetravel entries */
|
||||
InvalidateSystemCaches();
|
||||
|
||||
/* Decode until we run out of records */
|
||||
while ((startptr != InvalidXLogRecPtr && startptr < end_of_wal) ||
|
||||
(ctx->reader->EndRecPtr != InvalidXLogRecPtr && ctx->reader->EndRecPtr < end_of_wal))
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "access/transam.h"
|
||||
#include "access/xact.h"
|
||||
#include "access/xlog_internal.h"
|
||||
#include "access/xlogutils.h"
|
||||
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/dbcommands.h"
|
||||
@@ -721,6 +722,12 @@ logical_read_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int req
|
||||
XLogRecPtr flushptr;
|
||||
int count;
|
||||
|
||||
XLogReadDetermineTimeline(state, targetPagePtr, reqLen);
|
||||
sendTimeLineIsHistoric = (state->currTLI != ThisTimeLineID);
|
||||
sendTimeLine = state->currTLI;
|
||||
sendTimeLineValidUpto = state->currTLIValidUntil;
|
||||
sendTimeLineNextTLI = state->nextTLI;
|
||||
|
||||
/* make sure we have enough WAL available */
|
||||
flushptr = WalSndWaitForWal(targetPagePtr + reqLen);
|
||||
|
||||
@@ -974,10 +981,6 @@ StartLogicalReplication(StartReplicationCmd *cmd)
|
||||
pq_endmessage(&buf);
|
||||
pq_flush();
|
||||
|
||||
/* setup state for XLogReadPage */
|
||||
sendTimeLineIsHistoric = false;
|
||||
sendTimeLine = ThisTimeLineID;
|
||||
|
||||
/*
|
||||
* Initialize position to the last ack'ed one, then the xlog records begin
|
||||
* to be shipped from that position.
|
||||
|
||||
Reference in New Issue
Block a user