236 fpPtr =
ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize));
237 MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize));
240 fpEndPtr = fpPtr + (TotalProcs * (fpLockBitsSize + fpRelIdSize));
242 for (
i = 0;
i < TotalProcs;
i++)
253 fpPtr += fpLockBitsSize;
256 fpPtr += fpRelIdSize;
258 Assert(fpPtr <= fpEndPtr);
323 Assert(fpPtr == fpEndPtr);
350 elog(
PANIC,
"proc header uninitialized");
403 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
404 errmsg(
"number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
407 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
408 errmsg(
"sorry, too many clients already")));
446#ifdef USE_ASSERT_CHECKING
519 AttachSharedMemoryStructs();
576 elog(
PANIC,
"proc header uninitialized");
601 if (auxproc->
pid == 0)
607 elog(
FATAL,
"all AuxiliaryProcs are in use");
642#ifdef USE_ASSERT_CHECKING
693 AttachSharedMemoryStructs();
752 return (*nfree == n);
776 if (lockAwaited == NULL)
877 elog(
PANIC,
"ProcKill() called in child process");
882#ifdef USE_ASSERT_CHECKING
929 else if (leader !=
MyProc)
999 elog(
PANIC,
"AuxiliaryProcKill() called in child process");
1052 if (proc->
pid == pid)
1097 PGPROC *insert_before = NULL;
1100 bool early_deadlock =
false;
1122 myProcHeldLocks = proclock->
holdMask;
1123 myHeldLocks = myProcHeldLocks;
1135 myHeldLocks |= otherproclock->
holdMask;
1187 early_deadlock =
true;
1191 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1201 insert_before = proc;
1265 bool allow_autovacuum_cancel =
true;
1266 bool logged_recovery_conflict =
false;
1362 bool maybe_log_conflict =
1363 (standbyWaitStart != 0 && !logged_recovery_conflict);
1367 maybe_log_conflict);
1373 if (maybe_log_conflict)
1394 standbyWaitStart,
now,
1395 cnt > 0 ? vxids : NULL,
true);
1396 logged_recovery_conflict =
true;
1429 uint8 lockmethod_copy;
1444 locktag_copy = lock->
tag;
1454 int pid = autovac->
pid;
1466 "Process %d waits for %s on %s.",
1481 if (
kill(pid, SIGINT) < 0)
1495 (
errmsg(
"could not send signal to process %d: %m",
1501 allow_autovacuum_cancel =
false;
1513 const char *modename;
1519 bool first_holder =
true,
1520 first_waiter =
true;
1521 int lockHoldersNum = 0;
1533 msecs = secs * 1000 + usecs / 1000;
1534 usecs = usecs % 1000;
1562 first_waiter =
false;
1574 first_holder =
false;
1588 (
errmsg(
"process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1591 "Processes holding the lock: %s. Wait queue: %s.",
1592 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1603 (
errmsg(
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1606 "Processes holding the lock: %s. Wait queue: %s.",
1607 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1612 (
errmsg(
"process %d still waiting for %s on %s after %ld.%03d ms",
1615 "Processes holding the lock: %s. Wait queue: %s.",
1616 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1619 (
errmsg(
"process %d acquired %s on %s after %ld.%03d ms",
1636 (
errmsg(
"process %d failed to acquire %s on %s after %ld.%03d ms",
1639 "Processes holding the lock: %s. Wait queue: %s.",
1640 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1691 return myWaitStatus;
1754 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1816 if (Debug_deadlocks)
1872 int save_errno = errno;
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
int autovacuum_worker_slots
int AutovacuumLauncherPid
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)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
#define MemSet(start, val, len)
#define TRANSACTION_STATUS_IN_PROGRESS
bool ConditionVariableCancelSleep(void)
PGPROC * GetBlockingAutoVacuumPgproc(void)
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
void InitDeadLockChecking(void)
DeadLockState DeadLockCheck(PGPROC *proc)
int errmsg_internal(const char *fmt,...)
bool message_level_is_interesting(int elevel)
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 errdetail_log(const char *fmt,...)
#define ereport(elevel,...)
static dlist_node * dlist_pop_head_node(dlist_head *head)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
static void dclist_push_tail(dclist_head *head, dlist_node *node)
static void dlist_delete(dlist_node *node)
static bool dclist_is_empty(const dclist_head *head)
static bool dlist_node_is_detached(const dlist_node *node)
static void dlist_push_head(dlist_head *head, dlist_node *node)
static bool dlist_is_empty(const dlist_head *head)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static void dclist_delete_from_thoroughly(dclist_head *head, dlist_node *node)
static void dclist_insert_before(dclist_head *head, dlist_node *before, dlist_node *node)
#define dclist_foreach_modify(iter, lhead)
static void dlist_node_init(dlist_node *node)
#define dlist_container(type, membername, ptr)
#define dclist_foreach(iter, lhead)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
void OwnLatch(Latch *latch)
void DisownLatch(Latch *latch)
void InitSharedLatch(Latch *latch)
void SetLatch(Latch *latch)
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
#define WL_EXIT_ON_PM_DEATH
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
void GrantAwaitedLock(void)
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
void AbortStrongLockAcquire(void)
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
LOCALLOCK * GetAwaitedLock(void)
int FastPathLockGroupsPerBackend
uint32 LockTagHashCode(const LOCKTAG *locktag)
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
#define DEFAULT_LOCKMETHOD
#define LockHashPartitionLock(hashcode)
#define InvalidLocalTransactionId
@ DS_BLOCKED_BY_AUTOVACUUM
#define LOCKBIT_ON(lockmode)
#define LockHashPartitionLockByProc(leader_pgproc)
#define LockHashPartitionLockByIndex(i)
#define AccessExclusiveLock
bool LWLockHeldByMe(LWLock *lock)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void LWLockReleaseAll(void)
void LWLockInitialize(LWLock *lock, int tranche_id)
void InitLWLockAccess(void)
#define NUM_LOCK_PARTITIONS
@ LWTRANCHE_LOCK_FASTPATH
void pfree(void *pointer)
#define RESUME_INTERRUPTS()
#define AmAutoVacuumWorkerProcess()
#define AmBackgroundWorkerProcess()
#define CHECK_FOR_INTERRUPTS()
#define AmWalSenderProcess()
#define HOLD_INTERRUPTS()
#define AmSpecialWorkerProcess()
#define AmRegularBackendProcess()
void SwitchToSharedLatch(void)
void SwitchBackToLocalLatch(void)
void RegisterPostmasterChildActive(void)
void PGSemaphoreReset(PGSemaphore sema)
PGSemaphore PGSemaphoreCreate(void)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
#define NUM_AUXILIARY_PROCS
#define PROC_VACUUM_FOR_WRAPAROUND
#define FP_LOCK_SLOTS_PER_GROUP
#define GetNumberFromPGProc(proc)
#define NUM_SPECIAL_WORKER_PROCS
@ PROC_WAIT_STATUS_WAITING
#define PROC_IS_AUTOVACUUM
void ProcArrayAdd(PGPROC *proc)
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
#define INVALID_PROC_NUMBER
@ PROCSIG_RECOVERY_CONFLICT_LOCK
void set_spins_per_delay(int shared_spins_per_delay)
int update_spins_per_delay(int shared_spins_per_delay)
#define DEFAULT_SPINS_PER_DELAY
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
void * ShmemAlloc(Size size)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
static pg_noinline void Size size
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
ProcWaitStatus JoinWaitQueue(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
void ProcSendSignal(ProcNumber procNumber)
Size ProcGlobalShmemSize(void)
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
bool HaveNFreeProcs(int n, int *nfree)
static void RemoveProcFromArray(int code, Datum arg)
void InitAuxiliaryProcess(void)
PGPROC * PreparedXactProcs
static DeadLockState deadlock_state
int IdleInTransactionSessionTimeout
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
int GetStartupBufferPinWaitBufId(void)
ProcWaitStatus ProcSleep(LOCALLOCK *locallock)
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
static void CheckDeadLock(void)
NON_EXEC_STATIC slock_t * ProcStructLock
int ProcGlobalSemas(void)
void ProcReleaseLocks(bool isCommit)
void LockErrorCleanup(void)
bool BecomeLockGroupMember(PGPROC *leader, int pid)
void BecomeLockGroupLeader(void)
static void ProcKill(int code, Datum arg)
void CheckDeadLockAlert(void)
void InitProcessPhase2(void)
void InitProcGlobal(void)
static volatile sig_atomic_t got_deadlock_timeout
PGPROC * AuxiliaryPidGetProc(int pid)
void SetStartupBufferPinWaitBufId(int bufid)
void ProcWaitForSignal(uint32 wait_event_info)
static void AuxiliaryProcKill(int code, Datum arg)
void CheckRecoveryConflictDeadlock(void)
bool log_recovery_conflict_waits
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
void appendStringInfo(StringInfo str, const char *fmt,...)
void initStringInfo(StringInfo str)
uint8 locktag_lockmethodid
const LOCKMASK * conflictTab
bool procArrayGroupMember
XLogRecPtr clogGroupMemberLsn
pg_atomic_uint32 procArrayGroupNext
dlist_head lockGroupMembers
dlist_head * procgloballist
bool recoveryConflictPending
TransactionId clogGroupMemberXid
int64 clogGroupMemberPage
pg_atomic_uint64 waitStart
pg_atomic_uint32 clogGroupNext
XidStatus clogGroupMemberXidStatus
LocalTransactionId fpLocalTransactionId
TransactionId procArrayGroupMemberXid
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
ProcWaitStatus waitStatus
XidCacheStatus * subxidStates
dlist_head autovacFreeProcs
ProcNumber checkpointerProc
int startupBufferPinWaitBufId
pg_atomic_uint32 clogGroupFirst
dlist_head walsenderFreeProcs
dlist_head bgworkerFreeProcs
pg_atomic_uint32 procArrayGroupFirst
void SyncRepCleanupAtProcExit(void)
#define SYNC_REP_NOT_WAITING
void enable_timeout_after(TimeoutId id, int delay_ms)
TimestampTz get_timeout_start_time(TimeoutId id)
void disable_timeout(TimeoutId id, bool keep_indicator)
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
#define InvalidTransactionId
void pgstat_set_wait_event_storage(uint32 *wait_event_info)
void pgstat_reset_wait_event_storage(void)
bool RecoveryInProgress(void)
#define InvalidXLogRecPtr
static struct link * links