diff options
-rw-r--r-- | contrib/test_decoding/expected/slot.out | 3 | ||||
-rw-r--r-- | src/backend/replication/logical/logicalfuncs.c | 13 | ||||
-rw-r--r-- | src/backend/replication/slotfuncs.c | 4 | ||||
-rw-r--r-- | src/backend/replication/walsender.c | 14 |
4 files changed, 31 insertions, 3 deletions
diff --git a/contrib/test_decoding/expected/slot.out b/contrib/test_decoding/expected/slot.out index 1000171530f..ea72bf9f157 100644 --- a/contrib/test_decoding/expected/slot.out +++ b/contrib/test_decoding/expected/slot.out @@ -143,7 +143,8 @@ SELECT slot_name FROM pg_create_physical_replication_slot('regression_slot3'); SELECT pg_replication_slot_advance('regression_slot3', '0/0'); -- invalid LSN ERROR: invalid target WAL LSN SELECT pg_replication_slot_advance('regression_slot3', '0/1'); -- error -ERROR: cannot advance replication slot that has not previously reserved WAL +ERROR: replication slot "regression_slot3" cannot be advanced +DETAIL: This slot has never previously reserved WAL, or has been invalidated. SELECT pg_drop_replication_slot('regression_slot3'); pg_drop_replication_slot -------------------------- diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index f5384f1df8c..fded8e82908 100644 --- a/src/backend/replication/logical/logicalfuncs.c +++ b/src/backend/replication/logical/logicalfuncs.c @@ -237,6 +237,19 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin LogicalOutputPrepareWrite, LogicalOutputWrite, NULL); + /* + * After the sanity checks in CreateDecodingContext, make sure the + * restart_lsn is valid. Avoid "cannot get changes" wording in this + * errmsg because that'd be confusingly ambiguous about no changes + * being available. + */ + if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("can no longer get changes from replication slot \"%s\"", + NameStr(*name)), + errdetail("This slot has never previously reserved WAL, or has been invalidated."))); + MemoryContextSwitchTo(oldcontext); /* diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index f776de3df7a..ae751e94e76 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -598,7 +598,9 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot advance replication slot that has not previously reserved WAL"))); + errmsg("replication slot \"%s\" cannot be advanced", + NameStr(*slotname)), + errdetail("This slot has never previously reserved WAL, or has been invalidated."))); /* * Check if the slot is not moving backwards. Physical slots rely simply diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 6c87f6087ce..8b55bbfcb2e 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -600,6 +600,12 @@ StartReplication(StartReplicationCmd *cmd) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot use a logical replication slot for physical replication"))); + + /* + * We don't need to verify the slot's restart_lsn here; instead we + * rely on the caller requesting the starting point to use. If the + * WAL segment doesn't exist, we'll fail later. + */ } /* @@ -1134,6 +1140,13 @@ StartLogicalReplication(StartReplicationCmd *cmd) (void) ReplicationSlotAcquire(cmd->slotname, SAB_Error); + if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot read from logical replication slot \"%s\"", + cmd->slotname), + errdetail("This slot has been invalidated because it exceeded the maximum reserved size."))); + /* * Force a disconnect, so that the decoding code doesn't need to care * about an eventual switch from running in recovery, to running in a @@ -1159,7 +1172,6 @@ StartLogicalReplication(StartReplicationCmd *cmd) WalSndPrepareWrite, WalSndWriteData, WalSndUpdateProgress); - WalSndSetState(WALSNDSTATE_CATCHUP); /* Send a CopyBothResponse message, and start streaming */ |