224#define STANDBY_INITIAL_WAIT_US 1000
287 Assert(still_waiting || wait_list == NULL);
290 msecs = secs * 1000 + usecs / 1000;
291 usecs = usecs % 1000;
329 errmsg(
"recovery still waiting after %ld.%03d ms: %s",
332 "Conflicting processes: %s.",
333 nprocs,
buf.data) : 0);
338 errmsg(
"recovery finished waiting after %ld.%03d ms: %s",
365 bool logged_recovery_conflict =
false;
402 if (waitStart != 0 && (!logged_recovery_conflict || !
waiting))
405 bool maybe_log_conflict;
406 bool maybe_update_title;
412 if (maybe_log_conflict || maybe_update_title)
419 if (maybe_update_title &&
430 if (maybe_log_conflict &&
434 logged_recovery_conflict =
true;
447 if (logged_recovery_conflict)
492 WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
503 snapshotConflictHorizon);
563 WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
652 if (
now >= ltime && ltime != 0)
737 if (logging_conflict)
920 errmsg(
"canceling statement due to conflict with recovery"),
921 errdetail(
"User transaction caused buffer deadlock with recovery.")));
999 elog(
DEBUG4,
"adding recovery lock: db %u rel %u", dbOid, relOid);
1009 xidentry->
head = NULL;
1015 key.relOid = relOid;
1021 xidentry->
head = lockentry;
1039 for (entry = xidentry->
head; entry != NULL; entry =
next)
1044 "releasing recovery lock: xid %u db %u rel %u",
1051 "RecoveryLockHash contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
1060 xidentry->
head = NULL;
1097 for (
i = 0;
i < nsubxids;
i++)
1218 elog(
PANIC,
"standby_redo: unknown op code %u", info);
1346 xlrec.
xcnt = CurrRunningXacts->
xcnt;
1367 "snapshot of %d running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1368 CurrRunningXacts->
xcnt,
1375 "snapshot of %d+%d running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1376 CurrRunningXacts->
xcnt, CurrRunningXacts->
subxcnt,
1425 xlrec.
dbOid = dbOid;
1459 bool relcacheInitFileInval)
1464 memset(&xlrec, 0,
sizeof(xlrec));
1468 xlrec.
nmsgs = nmsgs;
1482 const char *reasonDesc =
_(
"unknown reason");
1487 reasonDesc =
_(
"recovery conflict on buffer pin");
1490 reasonDesc =
_(
"recovery conflict on lock");
1493 reasonDesc =
_(
"recovery conflict on tablespace");
1496 reasonDesc =
_(
"recovery conflict on snapshot");
1499 reasonDesc =
_(
"recovery conflict on replication slot");
1502 reasonDesc =
_(
"recovery conflict on buffer deadlock");
1505 reasonDesc =
_(
"recovery conflict on database");
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
TimestampTz GetCurrentTimestamp(void)
Datum now(PG_FUNCTION_ARGS)
static void cleanup(void)
bool HoldingBufferPinThatDelaysRecovery(void)
#define Assert(condition)
#define OidIsValid(objectId)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void hash_destroy(HTAB *hashp)
void * hash_seq_search(HASH_SEQ_STATUS *status)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
static volatile sig_atomic_t waiting
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void VirtualXactLockTableCleanup(void)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
#define VirtualTransactionIdIsValid(vxid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
#define AccessExclusiveLock
struct xl_standby_lock xl_standby_lock
void LWLockRelease(LWLock *lock)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
#define ERRCODE_T_R_DEADLOCK_DETECTED
long pgstat_report_stat(bool force)
pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)
void ExpireAllKnownAssignedTransactionIds(void)
RunningTransactions GetRunningTransactionData(void)
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)
int CountDBBackends(Oid databaseid)
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
@ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN
@ PROCSIG_RECOVERY_CONFLICT_LOCK
@ PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT
@ PROCSIG_RECOVERY_CONFLICT_DATABASE
@ PROCSIG_RECOVERY_CONFLICT_SNAPSHOT
@ PROCSIG_RECOVERY_CONFLICT_TABLESPACE
@ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK
void set_ps_display_remove_suffix(void)
void set_ps_display_suffix(const char *suffix)
bool update_process_title
void pg_usleep(long microsec)
void SharedInvalBackendInit(bool sendOnly)
LocalTransactionId GetNextLocalTransactionId(void)
bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
void ProcWaitForSignal(uint32 wait_event_info)
void standby_redo(XLogReaderState *record)
void ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
static bool WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
static volatile sig_atomic_t got_standby_deadlock_timeout
static TimestampTz GetStandbyLimitTime(void)
void StandbyTimeoutHandler(void)
void ResolveRecoveryConflictWithBufferPin(void)
static volatile sig_atomic_t got_standby_delay_timeout
void StandbyLockTimeoutHandler(void)
static int standbyWait_us
static void StandbyReleaseXidEntryLocks(RecoveryLockXidEntry *xidentry)
void StandbyDeadLockHandler(void)
static HTAB * RecoveryLockXidHash
XLogRecPtr LogStandbySnapshot(void)
struct RecoveryLockEntry RecoveryLockEntry
void CheckRecoveryConflictDeadlock(void)
void InitRecoveryTransactionEnvironment(void)
void ResolveRecoveryConflictWithTablespace(Oid tsid)
static const char * get_recovery_conflict_desc(ProcSignalReason reason)
bool log_recovery_conflict_waits
#define STANDBY_INITIAL_WAIT_US
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
static volatile sig_atomic_t got_standby_lock_timeout
void ResolveRecoveryConflictWithDatabase(Oid dbid)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
void StandbyReleaseOldLocks(TransactionId oldxid)
struct RecoveryLockXidEntry RecoveryLockXidEntry
void ResolveRecoveryConflictWithSnapshot(TransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
void LogAccessExclusiveLockPrepare(void)
static HTAB * RecoveryLockHash
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
static void StandbyReleaseLocks(TransactionId xid)
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
int max_standby_archive_delay
void StandbyReleaseAllLocks(void)
int max_standby_streaming_delay
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
void ShutdownRecoveryTransactionEnvironment(void)
#define MinSizeOfXactRunningXacts
#define XLOG_INVALIDATIONS
#define MinSizeOfInvalidations
#define XLOG_STANDBY_LOCK
#define XLOG_RUNNING_XACTS
void appendStringInfo(StringInfo str, const char *fmt,...)
void initStringInfo(StringInfo str)
pg_atomic_uint64 waitStart
struct RecoveryLockEntry * next
struct RecoveryLockEntry * head
TransactionId oldestRunningXid
TransactionId latestCompletedXid
subxids_array_status subxid_status
LocalTransactionId localTransactionId
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
bool relcacheInitFileInval
TransactionId latestCompletedXid
TransactionId oldestRunningXid
TransactionId xids[FLEXIBLE_ARRAY_MEMBER]
xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER]
void disable_all_timeouts(bool keep_indicators)
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
@ STANDBY_DEADLOCK_TIMEOUT
bool TransactionIdDidCommit(TransactionId transactionId)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool TransactionIdDidAbort(TransactionId transactionId)
#define InvalidTransactionId
#define U64FromFullTransactionId(x)
#define XidFromFullTransactionId(x)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
bool StandbyTransactionIdIsPrepared(TransactionId xid)
#define TimestampTzPlusMilliseconds(tz, ms)
FullTransactionId ReadNextFullTransactionId(void)
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
TransactionId GetCurrentTransactionId(void)
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
#define XLOG_MARK_UNIMPORTANT
#define XLogStandbyInfoActive()
#define LSN_FORMAT_ARGS(lsn)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogSetRecordFlags(uint8 flags)
void XLogRegisterData(const char *data, uint32 len)
void XLogBeginInsert(void)
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
#define XLogRecHasAnyBlockRefs(decoder)
void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
HotStandbyState standbyState