92 RecoveryLockLists =
hash_create(
"RecoveryLockLists",
142 RecoveryLockLists = NULL;
185 #define STANDBY_INITIAL_WAIT_US 1000 248 Assert(still_waiting || wait_list == NULL);
251 msecs = secs * 1000 + usecs / 1000;
252 usecs = usecs % 1000;
290 errmsg(
"recovery still waiting after %ld.%03d ms: %s",
293 "Conflicting processes: %s.",
294 nprocs, buf.
data) : 0);
299 errmsg(
"recovery finished waiting after %ld.%03d ms: %s",
325 char *new_status = NULL;
326 bool logged_recovery_conflict =
false;
363 if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL))
366 bool maybe_log_conflict;
367 bool maybe_update_title;
373 if (maybe_log_conflict || maybe_update_title)
380 if (maybe_update_title &&
383 const char *old_status;
387 new_status = (
char *)
palloc(len + 8 + 1);
388 memcpy(new_status, old_status, len);
389 strcpy(new_status + len,
" waiting");
391 new_status[len] =
'\0';
398 if (maybe_log_conflict &&
402 logged_recovery_conflict =
true;
415 if (logged_recovery_conflict)
633 if (logging_conflict)
812 (
errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
813 errmsg(
"canceling statement due to conflict with recovery"),
814 errdetail(
"User transaction caused buffer deadlock with recovery.")));
897 "adding recovery lock: db %u rel %u", dbOid, relOid);
912 newlock->
dbOid = dbOid;
930 "releasing recovery lock: xid %u db %u rel %u",
936 "RecoveryLockLists contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
976 for (i = 0; i < nsubxids; i++)
1054 for (i = 0; i < xlrec->
nlocks; i++)
1085 elog(
PANIC,
"standby_redo: unknown op code %u", info);
1220 xlrec.
xcnt = CurrRunningXacts->
xcnt;
1241 "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1242 CurrRunningXacts->
xcnt,
1249 "snapshot of %u+%u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1250 CurrRunningXacts->
xcnt, CurrRunningXacts->
subxcnt,
1299 xlrec.
dbOid = dbOid;
1333 bool relcacheInitFileInval)
1338 memset(&xlrec, 0,
sizeof(xlrec));
1342 xlrec.
nmsgs = nmsgs;
1356 const char *reasonDesc =
gettext_noop(
"unknown reason");
1361 reasonDesc =
gettext_noop(
"recovery conflict on buffer pin");
1364 reasonDesc =
gettext_noop(
"recovery conflict on lock");
1367 reasonDesc =
gettext_noop(
"recovery conflict on tablespace");
1370 reasonDesc =
gettext_noop(
"recovery conflict on snapshot");
1373 reasonDesc =
gettext_noop(
"recovery conflict on buffer deadlock");
1376 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
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)
void ExpireAllKnownAssignedTransactionIds(void)
int trace_recovery(int trace_level)
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)
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 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 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 pgstat_report_wait_end(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)
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)
#define PG_WAIT_BUFFER_PIN
void InitRecoveryTransactionEnvironment(void)
#define Assert(condition)
#define XLOG_MARK_UNIMPORTANT
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
bool HoldingBufferPinThatDelaysRecovery(void)
static void pgstat_report_wait_start(uint32 wait_event_info)
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
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)
#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)