131 size =
add_size(size,
mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
146 size =
add_size(size,
sizeof(slock_t));
243 MemSet(ptr, 0, requestSize);
246 ptr = (
char *) ptr + TotalProcs *
sizeof(
PGPROC);
269 Assert((ptr > (
char *) procs) && (ptr <= (
char *) procs + requestSize));
285 MemSet(fpPtr, 0, requestSize);
288 fpEndPtr = fpPtr + requestSize;
290 for (
i = 0;
i < TotalProcs;
i++)
301 fpPtr += fpLockBitsSize;
304 fpPtr += fpRelIdSize;
306 Assert(fpPtr <= fpEndPtr);
371 Assert(fpPtr == fpEndPtr);
400 elog(
PANIC,
"proc header uninitialized");
453 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
454 errmsg(
"number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
457 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
458 errmsg(
"sorry, too many clients already")));
496#ifdef USE_ASSERT_CHECKING
569 AttachSharedMemoryStructs();
626 elog(
PANIC,
"proc header uninitialized");
651 if (auxproc->
pid == 0)
657 elog(
FATAL,
"all AuxiliaryProcs are in use");
692#ifdef USE_ASSERT_CHECKING
743 AttachSharedMemoryStructs();
802 return (*nfree == n);
826 if (lockAwaited == NULL)
929 elog(
PANIC,
"ProcKill() called in child process");
934#ifdef USE_ASSERT_CHECKING
981 else if (leader !=
MyProc)
1051 elog(
PANIC,
"AuxiliaryProcKill() called in child process");
1104 if (proc->
pid == pid)
1149 PGPROC *insert_before = NULL;
1152 bool early_deadlock =
false;
1174 myProcHeldLocks = proclock->
holdMask;
1175 myHeldLocks = myProcHeldLocks;
1187 myHeldLocks |= otherproclock->
holdMask;
1239 early_deadlock =
true;
1243 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1253 insert_before = proc;
1317 bool allow_autovacuum_cancel =
true;
1318 bool logged_recovery_conflict =
false;
1414 bool maybe_log_conflict =
1415 (standbyWaitStart != 0 && !logged_recovery_conflict);
1419 maybe_log_conflict);
1425 if (maybe_log_conflict)
1446 standbyWaitStart,
now,
1447 cnt > 0 ? vxids : NULL,
true);
1448 logged_recovery_conflict =
true;
1481 uint8 lockmethod_copy;
1496 locktag_copy = lock->
tag;
1506 int pid = autovac->
pid;
1518 "Process %d waits for %s on %s.",
1533 if (
kill(pid, SIGINT) < 0)
1547 (
errmsg(
"could not send signal to process %d: %m",
1553 allow_autovacuum_cancel =
false;
1565 const char *modename;
1569 int lockHoldersNum = 0;
1581 msecs = secs * 1000 + usecs / 1000;
1582 usecs = usecs % 1000;
1587 &lock_waiters_sbuf, &lockHoldersNum);
1592 (
errmsg(
"process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1595 "Processes holding the lock: %s. Wait queue: %s.",
1596 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1607 (
errmsg(
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1610 "Processes holding the lock: %s. Wait queue: %s.",
1611 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1616 (
errmsg(
"process %d still waiting for %s on %s after %ld.%03d ms",
1619 "Processes holding the lock: %s. Wait queue: %s.",
1620 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1623 (
errmsg(
"process %d acquired %s on %s after %ld.%03d ms",
1640 (
errmsg(
"process %d failed to acquire %s on %s after %ld.%03d ms",
1643 "Processes holding the lock: %s. Wait queue: %s.",
1644 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1695 return myWaitStatus;
1758 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1820 if (Debug_deadlocks)
1876 int save_errno = errno;
1902 StringInfo lock_waiters_sbuf,
int *lockHoldersNum)
1907 bool first_holder =
true,
1908 first_waiter =
true;
1910#ifdef USE_ASSERT_CHECKING
1919 *lockHoldersNum = 0;
1944 first_waiter =
false;
1956 first_holder =
false;
1962 (*lockHoldersNum)++;
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 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,...)
Assert(PointerIsAligned(start, uint64))
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)
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 ResetAwaitedLock(void)
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 FastPathLockSlotsPerBackend()
#define PROC_VACUUM_FOR_WRAPAROUND
#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 * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
#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
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
int GetStartupBufferPinWaitBufId(void)
ProcWaitStatus ProcSleep(LOCALLOCK *locallock)
static Size PGProcShmemSize(void)
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
static Size FastPathLockShmemSize(void)
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)
#define WL_EXIT_ON_PM_DEATH
bool RecoveryInProgress(void)
#define InvalidXLogRecPtr
static struct link * links