92 RecoveryLockLists =
hash_create(
"RecoveryLockLists",
146 if (RecoveryLockLists == NULL)
157 RecoveryLockLists = NULL;
200 #define STANDBY_INITIAL_WAIT_US 1000 263 Assert(still_waiting || wait_list == NULL);
266 msecs = secs * 1000 + usecs / 1000;
267 usecs = usecs % 1000;
305 errmsg(
"recovery still waiting after %ld.%03d ms: %s",
308 "Conflicting processes: %s.",
309 nprocs, buf.
data) : 0);
314 errmsg(
"recovery finished waiting after %ld.%03d ms: %s",
340 char *new_status = NULL;
341 bool logged_recovery_conflict =
false;
378 if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL))
381 bool maybe_log_conflict;
382 bool maybe_update_title;
388 if (maybe_log_conflict || maybe_update_title)
395 if (maybe_update_title &&
398 const char *old_status;
402 new_status = (
char *)
palloc(len + 8 + 1);
403 memcpy(new_status, old_status, len);
404 strcpy(new_status + len,
" waiting");
406 new_status[len] =
'\0';
413 if (maybe_log_conflict &&
417 logged_recovery_conflict =
true;
430 if (logged_recovery_conflict)
613 if (now >= ltime && ltime != 0)
698 if (logging_conflict)
877 (
errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
878 errmsg(
"canceling statement due to conflict with recovery"),
879 errdetail(
"User transaction caused buffer deadlock with recovery.")));
962 "adding recovery lock: db %u rel %u", dbOid, relOid);
977 newlock->
dbOid = dbOid;
995 "releasing recovery lock: xid %u db %u rel %u",
1001 "RecoveryLockLists contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
1041 for (i = 0; i < nsubxids; i++)
1119 for (i = 0; i < xlrec->
nlocks; i++)
1150 elog(
PANIC,
"standby_redo: unknown op code %u", info);
1285 xlrec.
xcnt = CurrRunningXacts->
xcnt;
1306 "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1307 CurrRunningXacts->
xcnt,
1314 "snapshot of %u+%u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1315 CurrRunningXacts->
xcnt, CurrRunningXacts->
subxcnt,
1364 xlrec.
dbOid = dbOid;
1398 bool relcacheInitFileInval)
1403 memset(&xlrec, 0,
sizeof(xlrec));
1407 xlrec.
nmsgs = nmsgs;
1421 const char *reasonDesc =
gettext_noop(
"unknown reason");
1426 reasonDesc =
gettext_noop(
"recovery conflict on buffer pin");
1429 reasonDesc =
gettext_noop(
"recovery conflict on lock");
1432 reasonDesc =
gettext_noop(
"recovery conflict on tablespace");
1435 reasonDesc =
gettext_noop(
"recovery conflict on snapshot");
1438 reasonDesc =
gettext_noop(
"recovery conflict on buffer deadlock");
1441 reasonDesc =
gettext_noop(
"recovery conflict on database");
static volatile sig_atomic_t got_standby_deadlock_timeout
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
static bool WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
static void StandbyReleaseLockList(List *locks)
TransactionId oldestRunningXid
pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)
void hash_destroy(HTAB *hashp)
static TimestampTz GetStandbyLimitTime(void)
int CountDBBackends(Oid databaseid)
void StandbyTimeoutHandler(void)
int max_standby_archive_delay
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
void VirtualXactLockTableCleanup(void)
static HTAB * RecoveryLockLists
static void pgstat_report_wait_end(void)
void SharedInvalBackendInit(bool sendOnly)
bool update_process_title
TimestampTz GetCurrentTimestamp(void)
static void StandbyReleaseLocks(TransactionId xid)
int vacuum_defer_cleanup_age
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
#define XLOG_INVALIDATIONS
static int standbyWait_us
#define XLOG_STANDBY_LOCK
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
int errcode(int sqlerrcode)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
bool TransactionIdDidCommit(TransactionId transactionId)
LocalTransactionId localTransactionId
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
#define OidIsValid(objectId)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
void ExpireAllKnownAssignedTransactionIds(void)
int trace_recovery(int trace_level)
#define XidFromFullTransactionId(x)
TransactionId latestCompletedXid
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
void LWLockRelease(LWLock *lock)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
void set_ps_display(const char *activity)
TransactionId xids[FLEXIBLE_ARRAY_MEMBER]
void pg_usleep(long microsec)
#define LSN_FORMAT_ARGS(lsn)
pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
void pfree(void *pointer)
#define XLogRecGetData(decoder)
void disable_all_timeouts(bool keep_indicators)
void appendStringInfo(StringInfo str, const char *fmt,...)
XLogRecPtr LogStandbySnapshot(void)
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
void ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId latestRemovedFullXid, RelFileNode node)
void ResolveRecoveryConflictWithBufferPin(void)
#define STANDBY_INITIAL_WAIT_US
LocalTransactionId GetNextLocalTransactionId(void)
TransactionId latestCompletedXid
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
TransactionId GetCurrentTransactionId(void)
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
const char * get_ps_display(int *displen)
void standby_redo(XLogReaderState *record)
bool relcacheInitFileInval
#define MinSizeOfInvalidations
void LogAccessExclusiveLockPrepare(void)
int errdetail(const char *fmt,...)
#define PG_WAIT_BUFFER_PIN
#define InvalidTransactionId
bool StandbyTransactionIdIsPrepared(TransactionId xid)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void StandbyLockTimeoutHandler(void)
void StandbyDeadLockHandler(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
void CheckRecoveryConflictDeadlock(void)
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
void XLogSetRecordFlags(uint8 flags)
bool TransactionIdDidAbort(TransactionId transactionId)
bool log_recovery_conflict_waits
#define XLogRecGetInfo(decoder)
#define MinSizeOfXactRunningXacts
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
FullTransactionId ReadNextFullTransactionId(void)
static void pgstat_report_wait_start(uint32 wait_event_info)
List * lappend(List *list, void *datum)
void StandbyReleaseAllLocks(void)
void ProcWaitForSignal(uint32 wait_event_info)
void initStringInfo(StringInfo str)
#define VirtualTransactionIdIsValid(vxid)
void XLogRegisterData(char *data, int len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
static volatile sig_atomic_t got_standby_lock_timeout
static void cleanup(void)
#define XLogStandbyInfoActive()
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
#define TimestampTzPlusMilliseconds(tz, ms)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
#define ereport(elevel,...)
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
void ResolveRecoveryConflictWithTablespace(Oid tsid)
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
void ResolveRecoveryConflictWithDatabase(Oid dbid)
void InitRecoveryTransactionEnvironment(void)
#define Assert(condition)
#define XLOG_MARK_UNIMPORTANT
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
#define U64FromFullTransactionId(x)
bool HoldingBufferPinThatDelaysRecovery(void)
void * hash_seq_search(HASH_SEQ_STATUS *status)
xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER]
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
struct RecoveryLockListsEntry RecoveryLockListsEntry
#define AccessExclusiveLock
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
int errmsg(const char *fmt,...)
void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode node)
TransactionId oldestRunningXid
#define XLOG_RUNNING_XACTS
RunningTransactions GetRunningTransactionData(void)
#define XLogRecHasAnyBlockRefs(decoder)
void ShutdownRecoveryTransactionEnvironment(void)
#define CHECK_FOR_INTERRUPTS()
void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
static const char * get_recovery_conflict_desc(ProcSignalReason reason)
void disable_timeout(TimeoutId id, bool keep_indicator)
pg_atomic_uint64 waitStart
#define TransactionIdIsValid(xid)
static void static void status(const char *fmt,...) pg_attribute_printf(1
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
void XLogBeginInsert(void)
HotStandbyState standbyState
Datum now(PG_FUNCTION_ARGS)
#define offsetof(type, field)
void StandbyReleaseOldLocks(TransactionId oldxid)
int max_standby_streaming_delay
List * list_delete_first(List *list)
PGPROC * BackendIdGetProc(int backendID)