mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-15 02:46:59 +08:00
The logical decoding machinery already preserved all the required catalog tuples, which is sufficient in the course of normal logical decoding, but did not guarantee that non-catalog tuples were preserved during computation of the initial snapshot when creating a slot over the replication protocol. This could cause a corrupted initial snapshot being exported. The time window for issues is usually not terribly large, but on a busy server it's perfectly possible to it hit it. Ongoing decoding is not affected by this bug. To avoid increased overhead for the SQL API, only retain additional tuples when a logical slot is being created over the replication protocol. To do so this commit changes the signature of CreateInitDecodingContext(), but it seems unlikely that it's being used in an extension, so that's probably ok. In a drive-by fix, fix handling of ReplicationSlotsComputeRequiredXmin's already_locked argument, which should only apply to ProcArrayLock, not ReplicationSlotControlLock. Reported-By: Erik Rijkers Analyzed-By: Petr Jelinek Author: Petr Jelinek, heavily editorialized by Andres Freund Reviewed-By: Andres Freund Discussion: https://postgr.es/m/9a897b86-46e1-9915-ee4c-da02e4ff6a95@2ndquadrant.com Backport: 9.4, where logical decoding was introduced.
90 lines
3.4 KiB
C
90 lines
3.4 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* procarray.h
|
|
* POSTGRES process array definitions.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/storage/procarray.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef PROCARRAY_H
|
|
#define PROCARRAY_H
|
|
|
|
#include "storage/standby.h"
|
|
#include "utils/relcache.h"
|
|
#include "utils/snapshot.h"
|
|
|
|
|
|
extern Size ProcArrayShmemSize(void);
|
|
extern void CreateSharedProcArray(void);
|
|
extern void ProcArrayAdd(PGPROC *proc);
|
|
extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid);
|
|
|
|
extern void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid);
|
|
extern void ProcArrayClearTransaction(PGPROC *proc);
|
|
|
|
extern void ProcArrayInitRecovery(TransactionId initializedUptoXID);
|
|
extern void ProcArrayApplyRecoveryInfo(RunningTransactions running);
|
|
extern void ProcArrayApplyXidAssignment(TransactionId topxid,
|
|
int nsubxids, TransactionId *subxids);
|
|
|
|
extern void RecordKnownAssignedTransactionIds(TransactionId xid);
|
|
extern void ExpireTreeKnownAssignedTransactionIds(TransactionId xid,
|
|
int nsubxids, TransactionId *subxids,
|
|
TransactionId max_xid);
|
|
extern void ExpireAllKnownAssignedTransactionIds(void);
|
|
extern void ExpireOldKnownAssignedTransactionIds(TransactionId xid);
|
|
|
|
extern int GetMaxSnapshotXidCount(void);
|
|
extern int GetMaxSnapshotSubxidCount(void);
|
|
|
|
extern Snapshot GetSnapshotData(Snapshot snapshot);
|
|
|
|
extern bool ProcArrayInstallImportedXmin(TransactionId xmin,
|
|
TransactionId sourcexid);
|
|
extern bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc);
|
|
|
|
extern RunningTransactions GetRunningTransactionData(void);
|
|
|
|
extern bool TransactionIdIsInProgress(TransactionId xid);
|
|
extern bool TransactionIdIsActive(TransactionId xid);
|
|
extern TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum);
|
|
extern TransactionId GetOldestActiveTransactionId(void);
|
|
extern TransactionId GetOldestSafeDecodingTransactionId(bool catalogOnly);
|
|
|
|
extern VirtualTransactionId *GetVirtualXIDsDelayingChkpt(int *nvxids);
|
|
extern bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids);
|
|
|
|
extern PGPROC *BackendPidGetProc(int pid);
|
|
extern int BackendXidGetPid(TransactionId xid);
|
|
extern bool IsBackendPid(int pid);
|
|
|
|
extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin,
|
|
bool excludeXmin0, bool allDbs, int excludeVacuum,
|
|
int *nvxids);
|
|
extern VirtualTransactionId *GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid);
|
|
extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode);
|
|
|
|
extern bool MinimumActiveBackends(int min);
|
|
extern int CountDBBackends(Oid databaseid);
|
|
extern void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending);
|
|
extern int CountUserBackends(Oid roleid);
|
|
extern bool CountOtherDBBackends(Oid databaseId,
|
|
int *nbackends, int *nprepared);
|
|
|
|
extern void XidCacheRemoveRunningXids(TransactionId xid,
|
|
int nxids, const TransactionId *xids,
|
|
TransactionId latestXid);
|
|
|
|
extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
|
|
TransactionId catalog_xmin, bool already_locked);
|
|
|
|
extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
|
|
TransactionId *catalog_xmin);
|
|
|
|
#endif /* PROCARRAY_H */
|