130 size =
add_size(size,
mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
145 size =
add_size(size,
sizeof(slock_t));
242 MemSet(ptr, 0, requestSize);
245 ptr = (
char *) ptr + TotalProcs *
sizeof(
PGPROC);
268 Assert((ptr > (
char *) procs) && (ptr <= (
char *) procs + requestSize));
284 MemSet(fpPtr, 0, requestSize);
287 fpEndPtr = fpPtr + requestSize;
289 for (
i = 0;
i < TotalProcs;
i++)
300 fpPtr += fpLockBitsSize;
303 fpPtr += fpRelIdSize;
305 Assert(fpPtr <= fpEndPtr);
370 Assert(fpPtr == fpEndPtr);
399 elog(
PANIC,
"proc header uninitialized");
452 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
453 errmsg(
"number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
456 (
errcode(ERRCODE_TOO_MANY_CONNECTIONS),
457 errmsg(
"sorry, too many clients already")));
495#ifdef USE_ASSERT_CHECKING
568 AttachSharedMemoryStructs();
625 elog(
PANIC,
"proc header uninitialized");
650 if (auxproc->
pid == 0)
656 elog(
FATAL,
"all AuxiliaryProcs are in use");
691#ifdef USE_ASSERT_CHECKING
742 AttachSharedMemoryStructs();
801 return (*nfree == n);
825 if (lockAwaited == NULL)
928 elog(
PANIC,
"ProcKill() called in child process");
933#ifdef USE_ASSERT_CHECKING
980 else if (leader !=
MyProc)
1050 elog(
PANIC,
"AuxiliaryProcKill() called in child process");
1103 if (proc->
pid == pid)
1148 PGPROC *insert_before = NULL;
1151 bool early_deadlock =
false;
1173 myProcHeldLocks = proclock->
holdMask;
1174 myHeldLocks = myProcHeldLocks;
1186 myHeldLocks |= otherproclock->
holdMask;
1238 early_deadlock =
true;
1242 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1252 insert_before = proc;
1316 bool allow_autovacuum_cancel =
true;
1317 bool logged_recovery_conflict =
false;
1413 bool maybe_log_conflict =
1414 (standbyWaitStart != 0 && !logged_recovery_conflict);
1418 maybe_log_conflict);
1424 if (maybe_log_conflict)
1445 standbyWaitStart,
now,
1446 cnt > 0 ? vxids : NULL,
true);
1447 logged_recovery_conflict =
true;
1480 uint8 lockmethod_copy;
1495 locktag_copy = lock->
tag;
1505 int pid = autovac->
pid;
1517 "Process %d waits for %s on %s.",
1532 if (
kill(pid, SIGINT) < 0)
1546 (
errmsg(
"could not send signal to process %d: %m",
1552 allow_autovacuum_cancel =
false;
1564 const char *modename;
1568 int lockHoldersNum = 0;
1580 msecs = secs * 1000 + usecs / 1000;
1581 usecs = usecs % 1000;
1586 &lock_waiters_sbuf, &lockHoldersNum);
1591 (
errmsg(
"process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1594 "Processes holding the lock: %s. Wait queue: %s.",
1595 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1606 (
errmsg(
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1609 "Processes holding the lock: %s. Wait queue: %s.",
1610 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1615 (
errmsg(
"process %d still waiting for %s on %s after %ld.%03d ms",
1618 "Processes holding the lock: %s. Wait queue: %s.",
1619 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1622 (
errmsg(
"process %d acquired %s on %s after %ld.%03d ms",
1639 (
errmsg(
"process %d failed to acquire %s on %s after %ld.%03d ms",
1642 "Processes holding the lock: %s. Wait queue: %s.",
1643 lockHoldersNum, lock_holders_sbuf.
data, lock_waiters_sbuf.
data))));
1694 return myWaitStatus;
1757 if ((lockMethodTable->
conflictTab[lockmode] & aheadRequests) == 0 &&
1819 if (Debug_deadlocks)
1875 int save_errno = errno;
1901 StringInfo lock_waiters_sbuf,
int *lockHoldersNum)
1906 bool first_holder =
true,
1907 first_waiter =
true;
1909#ifdef USE_ASSERT_CHECKING
1918 *lockHoldersNum = 0;
1943 first_waiter =
false;
1955 first_holder =
false;
1961 (*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