diff options
| author | Alvaro Herrera | 2020-04-29 00:39:04 +0000 |
|---|---|---|
| committer | Alvaro Herrera | 2020-04-29 00:39:04 +0000 |
| commit | d0abe78d84274cc203f3d117b8006dc2164ca31a (patch) | |
| tree | 34df7310c6f1c9ca08b2df1aceb414d1255ed65c /src/backend/replication | |
| parent | 52b164c5a00095a34685e66bf64b009578b9cfda (diff) | |
Check slot->restart_lsn validity in a few more places
Lack of these checks could cause visible misbehavior, including
assertion failures. This was missed in commit c6550776394e, whereby
restart_lsn becomes invalid when the size limit is exceeded.
Also reword some existing error messages, and add errdetail(), so that
the reported errors all match in spirit.
Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/20200408.093710.447591748588426656.horikyota.ntt@gmail.com
Diffstat (limited to 'src/backend/replication')
| -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 |
3 files changed, 29 insertions, 2 deletions
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index f5384f1df8..fded8e8290 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 f776de3df7..ae751e94e7 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 6c87f6087c..8b55bbfcb2 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 */ |
