PostgreSQL Source Code: src/include/storage/standby.h File Reference (original) (raw)
Go to the source code of this file.
Variables | |
---|---|
PGDLLIMPORT int | max_standby_archive_delay |
PGDLLIMPORT int | max_standby_streaming_delay |
PGDLLIMPORT bool | log_recovery_conflict_waits |
◆ MinSizeOfXactRunningXacts
◆ RunningTransactions
◆ RunningTransactionsData
◆ subxids_array_status
Enumerator |
---|
SUBXIDS_IN_ARRAY |
SUBXIDS_MISSING |
SUBXIDS_IN_SUBTRANS |
Definition at line 78 of file standby.h.
◆ CheckRecoveryConflictDeadlock()
void CheckRecoveryConflictDeadlock | ( | void | ) |
---|
Definition at line 905 of file standby.c.
906{
908
910 return;
911
912
913
914
915
916
917
918
921 errmsg("canceling statement due to conflict with recovery"),
922 errdetail("User transaction caused buffer deadlock with recovery.")));
923}
bool HoldingBufferPinThatDelaysRecovery(void)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
#define ERRCODE_T_R_DEADLOCK_DETECTED
References Assert(), ereport, errcode(), ERRCODE_T_R_DEADLOCK_DETECTED, errdetail(), errmsg(), ERROR, HoldingBufferPinThatDelaysRecovery(), and InRecovery.
Referenced by ProcSleep().
◆ InitRecoveryTransactionEnvironment()
void InitRecoveryTransactionEnvironment | ( | void | ) |
---|
Definition at line 95 of file standby.c.
96{
99
101
102
103
104
105
109 64,
110 &hash_ctl,
115 64,
116 &hash_ctl,
118
119
120
121
122
123
124
126
127
128
129
130
131
132
133
134
135
136
137
138
143
145}
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
struct xl_standby_lock xl_standby_lock
void SharedInvalBackendInit(bool sendOnly)
LocalTransactionId GetNextLocalTransactionId(void)
static HTAB * RecoveryLockXidHash
struct RecoveryLockEntry RecoveryLockEntry
struct RecoveryLockXidEntry RecoveryLockXidEntry
static HTAB * RecoveryLockHash
LocalTransactionId localTransactionId
HotStandbyState standbyState
References Assert(), HASHCTL::entrysize, GetNextLocalTransactionId(), HASH_BLOBS, hash_create(), HASH_ELEM, HASHCTL::keysize, VirtualTransactionId::localTransactionId, MyProc, MyProcNumber, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryLockHash, RecoveryLockXidHash, SharedInvalBackendInit(), STANDBY_INITIALIZED, standbyState, VirtualXactLockTableInsert(), and PGPROC::vxid.
Referenced by StartupXLOG().
◆ LogAccessExclusiveLock()
void LogAccessExclusiveLock | ( | Oid | dbOid, |
---|---|---|---|
Oid | relOid | ||
) |
◆ LogAccessExclusiveLockPrepare()
void LogAccessExclusiveLockPrepare | ( | void | ) |
---|
◆ LogRecoveryConflict()
Definition at line 274 of file standby.c.
277{
278 long secs;
279 int usecs;
280 long msecs;
282 int nprocs = 0;
283
284
285
286
287
288 Assert(still_waiting || wait_list == NULL);
289
291 msecs = secs * 1000 + usecs / 1000;
292 usecs = usecs % 1000;
293
294 if (wait_list)
295 {
297
298
299 vxids = wait_list;
301 {
303
304
305 if (proc)
306 {
307 if (nprocs == 0)
308 {
311 }
312 else
314
315 nprocs++;
316 }
317
318 vxids++;
319 }
320 }
321
322
323
324
325
326
327 if (still_waiting)
328 {
330 errmsg("recovery still waiting after %ld.%03d ms: %s",
333 "Conflicting processes: %s.",
334 nprocs, buf.data) : 0);
335 }
336 else
337 {
339 errmsg("recovery finished waiting after %ld.%03d ms: %s",
341 }
342
343 if (nprocs > 0)
345}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Datum now(PG_FUNCTION_ARGS)
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
#define VirtualTransactionIdIsValid(vxid)
void pfree(void *pointer)
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
static const char * get_recovery_conflict_desc(ProcSignalReason reason)
void appendStringInfo(StringInfo str, const char *fmt,...)
void initStringInfo(StringInfo str)
References appendStringInfo(), Assert(), buf, ereport, errdetail_log_plural(), errmsg(), get_recovery_conflict_desc(), initStringInfo(), LOG, now(), pfree(), PGPROC::pid, VirtualTransactionId::procNumber, ProcNumberGetProc(), TimestampDifference(), and VirtualTransactionIdIsValid.
Referenced by LockBufferForCleanup(), ProcSleep(), and ResolveRecoveryConflictWithVirtualXIDs().
◆ LogStandbyInvalidations()
Definition at line 1470 of file standby.c.
1472{
1474
1475
1476 memset(&xlrec, 0, sizeof(xlrec));
1480 xlrec.nmsgs = nmsgs;
1481
1482
1488}
#define XLOG_INVALIDATIONS
#define MinSizeOfInvalidations
bool relcacheInitFileInval
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const void *data, uint32 len)
void XLogBeginInsert(void)
References xl_invalidations::dbId, MinSizeOfInvalidations, MyDatabaseId, MyDatabaseTableSpace, xl_invalidations::nmsgs, xl_invalidations::relcacheInitFileInval, xl_invalidations::tsId, XLOG_INVALIDATIONS, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().
Referenced by RecordTransactionCommit().
◆ LogStandbySnapshot()
Definition at line 1282 of file standby.c.
1283{
1287 int nlocks;
1288
1290
1291#ifdef USE_INJECTION_POINTS
1293 {
1294
1295
1296
1297
1299 }
1300#endif
1301
1302
1303
1304
1306 if (nlocks > 0)
1309
1310
1311
1312
1313
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1330
1332
1333
1336
1337
1339
1340 return recptr;
1341}
#define IS_INJECTION_POINT_ATTACHED(name)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
void LWLockRelease(LWLock *lock)
RunningTransactions GetRunningTransactionData(void)
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
XLogRecPtr GetInsertRecPtr(void)
#define XLogStandbyInfoActive()
References Assert(), GetInsertRecPtr(), GetRunningTransactionData(), GetRunningTransactionLocks(), IS_INJECTION_POINT_ATTACHED, LogAccessExclusiveLocks(), LogCurrentRunningXacts(), LWLockRelease(), pfree(), wal_level, WAL_LEVEL_LOGICAL, and XLogStandbyInfoActive.
Referenced by BackgroundWriterMain(), CreateCheckPoint(), pg_log_standby_snapshot(), ReplicationSlotReserveWal(), and SnapBuildWaitSnapshot().
◆ ResolveRecoveryConflictWithBufferPin()
void ResolveRecoveryConflictWithBufferPin | ( | void | ) |
---|
Definition at line 793 of file standby.c.
794{
796
798
800
802 {
803
804
805
807 }
808 else
809 {
810
811
812
813
815 int cnt = 0;
816
817 if (ltime != 0)
818 {
821 timeouts[cnt].fin_time = ltime;
822 cnt++;
823 }
824
829 cnt++;
830
832 }
833
834
835
836
837
838
839
840
841
842
844
848 {
849
850
851
852
853
854
855
856
857
858
859
860
861
863 }
864
865
866
867
868
869
870
874}
TimestampTz GetCurrentTimestamp(void)
@ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN
@ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK
void ProcWaitForSignal(uint32 wait_event_info)
static volatile sig_atomic_t got_standby_deadlock_timeout
static TimestampTz GetStandbyLimitTime(void)
static volatile sig_atomic_t got_standby_delay_timeout
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
void disable_all_timeouts(bool keep_indicators)
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
@ STANDBY_DEADLOCK_TIMEOUT
References Assert(), DeadlockTimeout, EnableTimeoutParams::delay_ms, disable_all_timeouts(), enable_timeouts(), EnableTimeoutParams::fin_time, GetCurrentTimestamp(), GetStandbyLimitTime(), got_standby_deadlock_timeout, got_standby_delay_timeout, EnableTimeoutParams::id, InHotStandby, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, ProcWaitForSignal(), SendRecoveryConflictWithBufferPin(), STANDBY_DEADLOCK_TIMEOUT, STANDBY_TIMEOUT, TMPARAM_AFTER, TMPARAM_AT, and EnableTimeoutParams::type.
Referenced by LockBufferForCleanup().
◆ ResolveRecoveryConflictWithDatabase()
void ResolveRecoveryConflictWithDatabase | ( | Oid | dbid | ) |
---|
◆ ResolveRecoveryConflictWithLock()
void ResolveRecoveryConflictWithLock | ( | LOCKTAG | locktag, |
---|---|---|---|
bool | logging_conflict | ||
) |
Definition at line 623 of file standby.c.
624{
627
629
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
652
653 if (now >= ltime && ltime != 0)
654 {
655
656
657
659
661
662
663
664
665
666
670 false);
671 }
672 else
673 {
674
675
676
677
679 int cnt = 0;
680
681 if (ltime != 0)
682 {
686 timeouts[cnt].fin_time = ltime;
687 cnt++;
688 }
689
694 cnt++;
695
697 }
698
699
701
702
703
704
705
706
709
711 {
713
715
716
719
720
721
722
723
725 {
728 false);
729 backends++;
730 }
731
732
733
734
735
736
737
738 if (logging_conflict)
740
741
742
743
744
745
746
747
750 }
751
753
754
755
756
757
758
759
763}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
static void cleanup(void)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
#define AccessExclusiveLock
pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)
@ PROCSIG_RECOVERY_CONFLICT_LOCK
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
static volatile sig_atomic_t got_standby_lock_timeout
pg_atomic_uint64 waitStart
References AccessExclusiveLock, Assert(), cleanup(), DeadlockTimeout, EnableTimeoutParams::delay_ms, disable_all_timeouts(), enable_timeouts(), EnableTimeoutParams::fin_time, GetCurrentTimestamp(), GetLockConflicts(), GetStandbyLimitTime(), got_standby_deadlock_timeout, got_standby_lock_timeout, EnableTimeoutParams::id, InHotStandby, LOCKTAG::locktag_type, MyProc, now(), pg_atomic_read_u64(), pg_atomic_write_u64(), PG_WAIT_LOCK, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, ProcWaitForSignal(), ResolveRecoveryConflictWithVirtualXIDs(), SignalVirtualTransaction(), STANDBY_DEADLOCK_TIMEOUT, STANDBY_LOCK_TIMEOUT, TMPARAM_AFTER, TMPARAM_AT, EnableTimeoutParams::type, VirtualTransactionIdIsValid, and PGPROC::waitStart.
Referenced by ProcSleep().
◆ ResolveRecoveryConflictWithSnapshot()
Definition at line 468 of file standby.c.
471{
473
474
475
476
477
478
479
480
481
482
483
484
486 return;
487
493 WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
494 true);
495
496
497
498
499
500
501
504 snapshotConflictHorizon);
505}
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
@ PROCSIG_RECOVERY_CONFLICT_SNAPSHOT
bool InvalidateObsoleteReplicationSlots(uint32 possible_causes, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
References Assert(), RelFileLocator::dbOid, GetConflictingVirtualXIDs(), InvalidateObsoleteReplicationSlots(), PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, ResolveRecoveryConflictWithVirtualXIDs(), RS_INVAL_HORIZON, TransactionIdIsNormal, TransactionIdIsValid, wal_level, and WAL_LEVEL_LOGICAL.
Referenced by btree_xlog_delete(), gistRedoDeleteRecord(), hash_xlog_vacuum_one_page(), heap_xlog_prune_freeze(), heap_xlog_visible(), ResolveRecoveryConflictWithSnapshotFullXid(), and spgRedoVacuumRedirect().
◆ ResolveRecoveryConflictWithSnapshotFullXid()
◆ ResolveRecoveryConflictWithTablespace()
void ResolveRecoveryConflictWithTablespace | ( | Oid | tsid | ) |
---|
◆ ShutdownRecoveryTransactionEnvironment()
void ShutdownRecoveryTransactionEnvironment | ( | void | ) |
---|
◆ StandbyAcquireAccessExclusiveLock()
Definition at line 986 of file standby.c.
987{
992 bool found;
993
994
998 return;
999
1000 elog(DEBUG4, "adding recovery lock: db %u rel %u", dbOid, relOid);
1001
1002
1004
1005
1007 if (!found)
1008 {
1009 Assert(xidentry->xid == xid);
1010 xidentry->head = NULL;
1011 }
1012
1013
1014 key.xid = xid;
1015 key.dbOid = dbOid;
1016 key.relOid = relOid;
1018 if (!found)
1019 {
1020
1021 lockentry->next = xidentry->head;
1022 xidentry->head = lockentry;
1023
1024
1026
1028 }
1029}
#define OidIsValid(objectId)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
struct RecoveryLockEntry * next
struct RecoveryLockEntry * head
bool TransactionIdDidCommit(TransactionId transactionId)
bool TransactionIdDidAbort(TransactionId transactionId)
References AccessExclusiveLock, Assert(), DEBUG4, elog, HASH_ENTER, hash_search(), RecoveryLockXidEntry::head, sort-test::key, LockAcquire(), RecoveryLockEntry::next, OidIsValid, RecoveryLockHash, RecoveryLockXidHash, SET_LOCKTAG_RELATION, TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdIsValid, and RecoveryLockXidEntry::xid.
Referenced by lock_twophase_standby_recover(), and standby_redo().
◆ StandbyDeadLockHandler()
void StandbyDeadLockHandler | ( | void | ) |
---|
◆ StandbyLockTimeoutHandler()
void StandbyLockTimeoutHandler | ( | void | ) |
---|
◆ StandbyReleaseAllLocks()
void StandbyReleaseAllLocks | ( | void | ) |
---|
Definition at line 1106 of file standby.c.
1107{
1110
1111 elog(DEBUG2, "release all standby locks");
1112
1115 {
1118 }
1119}
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
static void StandbyReleaseXidEntryLocks(RecoveryLockXidEntry *xidentry)
References DEBUG2, elog, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockXidHash, and StandbyReleaseXidEntryLocks().
Referenced by ShutdownRecoveryTransactionEnvironment(), and StandbyReleaseLocks().
◆ StandbyReleaseLockTree()
◆ StandbyReleaseOldLocks()
Definition at line 1130 of file standby.c.
1131{
1134
1137 {
1139
1140
1142 continue;
1143
1144
1146 continue;
1147
1148
1151 }
1152}
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool StandbyTransactionIdIsPrepared(TransactionId xid)
References Assert(), HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockXidHash, StandbyReleaseXidEntryLocks(), StandbyTransactionIdIsPrepared(), TransactionIdIsValid, TransactionIdPrecedes(), and RecoveryLockXidEntry::xid.
Referenced by ProcArrayApplyRecoveryInfo().
◆ StandbyTimeoutHandler()
void StandbyTimeoutHandler | ( | void | ) |
---|