mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
Add additional checks while creating the initial decoding snapshot.
As per one of the CI reports, there is an assertion failure which indicates that we were trying to use an unenforced xmin horizon for decoding snapshots. Though, we couldn't figure out the reason for assertion failure these checks would help us in finding the reason if the problem happens again in the future. Author: Amit Kapila based on suggestions by Andres Freund Reviewd by: Andres Freund Discussion: https://postgr.es/m/CAA4eK1L8wYcyTPxNzPGkhuO52WBGoOZbT0A73Le=ZUWYAYmdfw@mail.gmail.com
This commit is contained in:
parent
a4adc31f69
commit
240e0dbacd
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user