202 #define STANDBY_INITIAL_WAIT_US 1000
265 Assert(still_waiting || wait_list == NULL);
268 msecs = secs * 1000 + usecs / 1000;
269 usecs = usecs % 1000;
307 errmsg(
"recovery still waiting after %ld.%03d ms: %s",
310 "Conflicting processes: %s.",
311 nprocs,
buf.data) : 0);
316 errmsg(
"recovery finished waiting after %ld.%03d ms: %s",
342 char *new_status = NULL;
343 bool logged_recovery_conflict =
false;
380 if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL))
383 bool maybe_log_conflict;
384 bool maybe_update_title;
390 if (maybe_log_conflict || maybe_update_title)
397 if (maybe_update_title &&
400 const char *old_status;
404 new_status = (
char *)
palloc(
len + 8 + 1);
405 memcpy(new_status, old_status,
len);
406 strcpy(new_status +
len,
" waiting");
408 new_status[
len] =
'\0';
415 if (maybe_log_conflict &&
419 logged_recovery_conflict =
true;
432 if (logged_recovery_conflict)
615 if (
now >= ltime && ltime != 0)
700 if (logging_conflict)
883 errmsg(
"canceling statement due to conflict with recovery"),
884 errdetail(
"User transaction caused buffer deadlock with recovery.")));
962 "adding recovery lock: db %u rel %u", dbOid, relOid);
977 newlock->
dbOid = dbOid;
997 "releasing recovery lock: xid %u db %u rel %u",
1003 "RecoveryLockLists contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
1043 for (
i = 0;
i < nsubxids;
i++)
1152 elog(
PANIC,
"standby_redo: unknown op code %u", info);
1287 xlrec.
xcnt = CurrRunningXacts->
xcnt;
1308 "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1309 CurrRunningXacts->
xcnt,
1316 "snapshot of %u+%u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1317 CurrRunningXacts->
xcnt, CurrRunningXacts->
subxcnt,
1366 xlrec.
dbOid = dbOid;
1400 bool relcacheInitFileInval)
1405 memset(&xlrec, 0,
sizeof(xlrec));
1409 xlrec.
nmsgs = nmsgs;
1423 const char *reasonDesc =
_(
"unknown reason");
1428 reasonDesc =
_(
"recovery conflict on buffer pin");
1431 reasonDesc =
_(
"recovery conflict on lock");
1434 reasonDesc =
_(
"recovery conflict on tablespace");
1437 reasonDesc =
_(
"recovery conflict on snapshot");
1440 reasonDesc =
_(
"recovery conflict on buffer deadlock");
1443 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 offsetof(type, field)
#define OidIsValid(objectId)
void hash_destroy(HTAB *hashp)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void * hash_seq_search(HASH_SEQ_STATUS *status)
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,...)
int trace_recovery(int trace_level)
#define ereport(elevel,...)
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
void list_free_deep(List *list)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void VirtualXactLockTableCleanup(void)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
#define VirtualTransactionIdIsValid(vxid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
#define AccessExclusiveLock
void LWLockRelease(LWLock *lock)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
static void static void status(const char *fmt,...) pg_attribute_printf(1
#define ERRCODE_T_R_DEADLOCK_DETECTED
pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)
void ExpireAllKnownAssignedTransactionIds(void)
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
RunningTransactions GetRunningTransactionData(void)
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)
int CountDBBackends(Oid databaseid)
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
@ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN
@ PROCSIG_RECOVERY_CONFLICT_LOCK
@ PROCSIG_RECOVERY_CONFLICT_DATABASE
@ PROCSIG_RECOVERY_CONFLICT_SNAPSHOT
@ PROCSIG_RECOVERY_CONFLICT_TABLESPACE
@ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK
const char * get_ps_display(int *displen)
bool update_process_title
void set_ps_display(const char *activity)
void pg_usleep(long microsec)
void SharedInvalBackendInit(bool sendOnly)
LocalTransactionId GetNextLocalTransactionId(void)
PGPROC * BackendIdGetProc(int backendID)
void ProcWaitForSignal(uint32 wait_event_info)
void standby_redo(XLogReaderState *record)
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
int vacuum_defer_cleanup_age
static void StandbyReleaseLockList(List *locks)
void StandbyLockTimeoutHandler(void)
static int standbyWait_us
void StandbyDeadLockHandler(void)
XLogRecPtr LogStandbySnapshot(void)
struct RecoveryLockListsEntry RecoveryLockListsEntry
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)
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
void LogAccessExclusiveLockPrepare(void)
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)
void ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId latestRemovedFullXid, RelFileNode node)
int max_standby_streaming_delay
void ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode node)
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
static HTAB * RecoveryLockLists
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
TransactionId oldestRunningXid
TransactionId latestCompletedXid
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)
bool StandbyTransactionIdIsPrepared(TransactionId xid)
#define TimestampTzPlusMilliseconds(tz, ms)
FullTransactionId ReadNextFullTransactionId(void)
@ WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE
@ WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT
#define PG_WAIT_BUFFER_PIN
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 XLogBeginInsert(void)
void XLogRegisterData(char *data, int len)
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
#define XLogRecHasAnyBlockRefs(decoder)
void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
HotStandbyState standbyState