aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/logical/snapbuild.c29
-rw-r--r--src/backend/replication/walsender.c5
2 files changed, 23 insertions, 11 deletions
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 556b7fcba38..a1fd1d92d63 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -566,11 +566,18 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
{
Snapshot snap;
TransactionId xid;
+ TransactionId safeXid;
TransactionId *newxip;
int newxcnt = 0;
- Assert(!FirstSnapshotSet);
Assert(XactIsoLevel == XACT_REPEATABLE_READ);
+ Assert(builder->building_full_snapshot);
+
+ /* don't allow older snapshots */
+ InvalidateCatalogSnapshot(); /* about to overwrite MyProc->xmin */
+ if (HaveRegisteredOrActiveSnapshot())
+ elog(ERROR, "cannot build an initial slot snapshot when snapshots exist");
+ Assert(!HistoricSnapshotActive());
if (builder->state != SNAPBUILD_CONSISTENT)
elog(ERROR, "cannot build an initial slot snapshot before reaching a consistent state");
@@ -588,18 +595,18 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
* We know that snap->xmin is alive, enforced by the logical xmin
* mechanism. Due to that we can do this without locks, we're only
* changing our own value.
+ *
+ * Building an initial snapshot is expensive and an unenforced xmin
+ * horizon would have bad consequences, therefore always double-check that
+ * the horizon is enforced.
*/
-#ifdef USE_ASSERT_CHECKING
- {
- TransactionId safeXid;
+ LWLockAcquire(ProcArrayLock, LW_SHARED);
+ safeXid = GetOldestSafeDecodingTransactionId(false);
+ LWLockRelease(ProcArrayLock);
- LWLockAcquire(ProcArrayLock, LW_SHARED);
- safeXid = GetOldestSafeDecodingTransactionId(false);
- LWLockRelease(ProcArrayLock);
-
- Assert(TransactionIdPrecedesOrEquals(safeXid, snap->xmin));
- }
-#endif
+ if (TransactionIdFollows(safeXid, snap->xmin))
+ elog(ERROR, "cannot build an initial slot snapshot as oldest safe xid %u follows snapshot's xmin %u",
+ safeXid, snap->xmin);
MyProc->xmin = snap->xmin;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index a81ef6a2014..c11bb3716f4 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1099,6 +1099,11 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
/*- translator: %s is a CREATE_REPLICATION_SLOT statement */
(errmsg("%s must be called in REPEATABLE READ isolation mode transaction",
"CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')")));
+ if (!XactReadOnly)
+ ereport(ERROR,
+ /*- translator: %s is a CREATE_REPLICATION_SLOT statement */
+ (errmsg("%s must be called in a read only transaction",
+ "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')")));
if (FirstSnapshotSet)
ereport(ERROR,