56 mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
113 "ShareUpdateExclusiveLock",
115 "ShareRowExclusiveLock",
117 "AccessExclusiveLock"
188 #define FAST_PATH_BITS_PER_SLOT 3
189 #define FAST_PATH_LOCKNUMBER_OFFSET 1
190 #define FAST_PATH_MASK ((1 << FAST_PATH_BITS_PER_SLOT) - 1)
191 #define FAST_PATH_GET_BITS(proc, n) \
192 (((proc)->fpLockBits >> (FAST_PATH_BITS_PER_SLOT * n)) & FAST_PATH_MASK)
193 #define FAST_PATH_BIT_POSITION(n, l) \
194 (AssertMacro((l) >= FAST_PATH_LOCKNUMBER_OFFSET), \
195 AssertMacro((l) < FAST_PATH_BITS_PER_SLOT+FAST_PATH_LOCKNUMBER_OFFSET), \
196 AssertMacro((n) < FP_LOCK_SLOTS_PER_BACKEND), \
197 ((l) - FAST_PATH_LOCKNUMBER_OFFSET + FAST_PATH_BITS_PER_SLOT * (n)))
198 #define FAST_PATH_SET_LOCKMODE(proc, n, l) \
199 (proc)->fpLockBits |= UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l)
200 #define FAST_PATH_CLEAR_LOCKMODE(proc, n, l) \
201 (proc)->fpLockBits &= ~(UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l))
202 #define FAST_PATH_CHECK_LOCKMODE(proc, n, l) \
203 ((proc)->fpLockBits & (UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l)))
213 #define EligibleForRelationFastPath(locktag, mode) \
214 ((locktag)->locktag_lockmethodid == DEFAULT_LOCKMETHOD && \
215 (locktag)->locktag_type == LOCKTAG_RELATION && \
216 (locktag)->locktag_field1 == MyDatabaseId && \
217 MyDatabaseId != InvalidOid && \
218 (mode) < ShareUpdateExclusiveLock)
219 #define ConflictsWithRelationFastPath(locktag, mode) \
220 ((locktag)->locktag_lockmethodid == DEFAULT_LOCKMETHOD && \
221 (locktag)->locktag_type == LOCKTAG_RELATION && \
222 (locktag)->locktag_field1 != InvalidOid && \
223 (mode) > ShareUpdateExclusiveLock)
246 #define FAST_PATH_STRONG_LOCK_HASH_BITS 10
247 #define FAST_PATH_STRONG_LOCK_HASH_PARTITIONS \
248 (1 << FAST_PATH_STRONG_LOCK_HASH_BITS)
249 #define FastPathStrongLockHashPartition(hashcode) \
250 ((hashcode) % FAST_PATH_STRONG_LOCK_HASH_PARTITIONS)
298 bool Trace_locks =
false;
299 bool Trace_userlocks =
false;
300 int Trace_lock_table = 0;
301 bool Debug_deadlocks =
false;
305 LOCK_DEBUG_ENABLED(
const LOCKTAG *tag)
310 || (Trace_lock_table &&
318 if (LOCK_DEBUG_ENABLED(&lock->
tag))
320 "%s: lock(%p) id(%u,%u,%u,%u,%u,%u) grantMask(%x) "
321 "req(%d,%d,%d,%d,%d,%d,%d)=%d "
322 "grant(%d,%d,%d,%d,%d,%d,%d)=%d wait(%d) type(%s)",
344 "%s: proclock(%p) lock(%p) method(%u) proc(%p) hold(%x)",
351 #define LOCK_PRINT(where, lock, type) ((void) 0)
352 #define PROCLOCK_PRINT(where, proclockP) ((void) 0)
374 bool decrement_strong_lock_count);
395 long init_table_size,
404 init_table_size = max_table_size / 2;
422 init_table_size *= 2;
554 uint32 lockhash = hashcode;
599 MemSet(&localtag, 0,
sizeof(localtag));
600 localtag.
lock = *locktag;
601 localtag.
mode = lockmode;
607 if (locallock && locallock->
nLocks > 0)
614 for (slockmode = lockmode + 1;
626 #ifdef USE_ASSERT_CHECKING
632 GetLockMethodLocalHash(
void)
652 bool hasWaiters =
false;
655 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
657 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
658 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
661 if (LOCK_DEBUG_ENABLED(locktag))
662 elog(
LOG,
"LockHasWaiters: lock [%u,%u] %s",
670 MemSet(&localtag, 0,
sizeof(localtag));
671 localtag.
lock = *locktag;
672 localtag.
mode = lockmode;
681 if (!locallock || locallock->
nLocks <= 0)
700 lock = locallock->
lock;
701 LOCK_PRINT(
"LockHasWaiters: found", lock, lockmode);
784 bool reportMemoryError,
798 bool log_lock =
false;
801 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
803 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
804 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
811 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
812 errmsg(
"cannot acquire lock mode %s on database objects while recovery is in progress",
814 errhint(
"Only RowExclusiveLock or less can be acquired on database objects during recovery.")));
817 if (LOCK_DEBUG_ENABLED(locktag))
818 elog(
LOG,
"LockAcquire: lock [%u,%u] %s",
832 MemSet(&localtag, 0,
sizeof(localtag));
833 localtag.
lock = *locktag;
834 localtag.
mode = lockmode;
845 locallock->
lock = NULL;
874 *locallockp = locallock;
882 if (locallock->
nLocks > 0)
896 Assert(!IsRelationExtensionLockHeld);
955 locallock->
lock = NULL;
977 if (locallock->
nLocks == 0)
981 if (reportMemoryError)
983 (
errcode(ERRCODE_OUT_OF_MEMORY),
984 errmsg(
"out of shared memory"),
985 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
1010 hashcode, lockmode);
1015 if (locallock->
nLocks == 0)
1019 if (reportMemoryError)
1021 (
errcode(ERRCODE_OUT_OF_MEMORY),
1022 errmsg(
"out of shared memory"),
1023 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
1029 locallock->
lock = lock;
1037 found_conflict =
true;
1042 if (!found_conflict)
1101 uint32 proclock_hashcode;
1112 elog(
PANIC,
"proclock table corrupted");
1118 LOCK_PRINT(
"LockAcquire: conditional lock failed",
1124 if (locallock->
nLocks == 0)
1137 LOCK_PRINT(
"LockAcquire: INCONSISTENT", lock, lockmode);
1143 LOCK_PRINT(
"LockAcquire: granted", lock, lockmode);
1189 uint32 proclock_hashcode;
1216 LOCK_PRINT(
"LockAcquire: new", lock, lockmode);
1220 LOCK_PRINT(
"LockAcquire: found", lock, lockmode);
1229 proclocktag.
myLock = lock;
1230 proclocktag.
myProc = proc;
1295 #ifdef CHECK_DEADLOCK_RISK
1318 if (
i >= (
int) lockmode)
1320 elog(
LOG,
"deadlock risk: raising lock level"
1321 " from %s to %s on object %u/%u/%u",
1347 elog(
ERROR,
"lock %s on object %u/%u/%u is already held",
1366 #ifdef USE_ASSERT_CHECKING
1368 IsRelationExtensionLockHeld = acquired;
1436 int conflictMask = lockMethodTable->
conflictTab[lockmode];
1438 int totalConflictsRemaining = 0;
1463 for (
i = 1;
i <= numLockModes;
i++)
1467 conflictsRemaining[
i] = 0;
1470 conflictsRemaining[
i] = lock->
granted[
i];
1472 --conflictsRemaining[
i];
1473 totalConflictsRemaining += conflictsRemaining[
i];
1477 if (totalConflictsRemaining == 0)
1479 PROCLOCK_PRINT(
"LockCheckConflicts: resolved (simple)", proclock);
1515 if (proclock != otherproclock &&
1517 (otherproclock->
holdMask & conflictMask) != 0)
1519 int intersectMask = otherproclock->
holdMask & conflictMask;
1521 for (
i = 1;
i <= numLockModes;
i++)
1525 if (conflictsRemaining[
i] <= 0)
1526 elog(
PANIC,
"proclocks held do not match lock");
1527 conflictsRemaining[
i]--;
1528 totalConflictsRemaining--;
1532 if (totalConflictsRemaining == 0)
1542 PROCLOCK_PRINT(
"LockCheckConflicts: conflicting (group)", proclock);
1584 bool wakeupNeeded =
false;
1598 if (lock->
granted[lockmode] == 0)
1604 LOCK_PRINT(
"UnGrantLock: updated", lock, lockmode);
1616 wakeupNeeded =
true;
1624 return wakeupNeeded;
1648 uint32 proclock_hashcode;
1659 elog(
PANIC,
"proclock table corrupted");
1668 LOCK_PRINT(
"CleanUpLock: deleting", lock, 0);
1677 else if (wakeupNeeded)
1703 if (lockOwners[
i].owner == owner)
1709 lockOwners[
i].
owner = owner;
1765 if (locallock == NULL)
1976 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
1978 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
1979 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
1982 if (LOCK_DEBUG_ENABLED(locktag))
1983 elog(
LOG,
"LockRelease: lock [%u,%u] %s",
1991 MemSet(&localtag, 0,
sizeof(localtag));
1992 localtag.
lock = *locktag;
1993 localtag.
mode = lockmode;
2002 if (!locallock || locallock->
nLocks <= 0)
2025 if (lockOwners[
i].owner == owner)
2027 Assert(lockOwners[
i].nLocks > 0);
2028 if (--lockOwners[
i].nLocks == 0)
2034 if (i < locallock->numLockOwners)
2055 if (locallock->
nLocks > 0)
2103 lock = locallock->
lock;
2115 elog(
ERROR,
"failed to re-find shared lock object");
2116 locallock->
lock = lock;
2118 proclocktag.
myLock = lock;
2125 elog(
ERROR,
"failed to re-find shared proclock object");
2127 LOCK_PRINT(
"LockRelease: found", lock, lockmode);
2148 wakeupNeeded =
UnGrantLock(lock, lockmode, proclock, lockMethodTable);
2151 lockMethodTable, locallock->
hashcode,
2178 bool have_fast_path_lwlock =
false;
2181 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2186 elog(
LOG,
"LockReleaseAll: lockmethod=%d", lockmethodid);
2217 if (locallock->
nLocks == 0)
2239 if (lockOwners[
i].owner == NULL)
2240 lockOwners[0] = lockOwners[
i];
2246 lockOwners[0].
owner == NULL &&
2247 lockOwners[0].
nLocks > 0)
2263 if (locallock->
proclock == NULL || locallock->
lock == NULL)
2270 elog(
PANIC,
"locallock table corrupted");
2280 if (!have_fast_path_lwlock)
2283 have_fast_path_lwlock =
true;
2300 have_fast_path_lwlock =
false;
2310 &locallock->
tag.
lock, lockmode,
false);
2316 if (locallock->
nLocks > 0)
2324 if (have_fast_path_lwlock)
2365 bool wakeupNeeded =
false;
2401 for (
i = 1;
i <= numLockModes;
i++)
2409 LOCK_PRINT(
"LockReleaseAll: updated", lock, 0);
2425 elog(
LOG,
"LockReleaseAll done");
2440 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2466 if (locallocks == NULL)
2480 for (
i = nlocks - 1;
i >= 0;
i--)
2515 if (lockOwners[
i].owner == owner)
2517 Assert(lockOwners[
i].nLocks > 0);
2518 if (lockOwners[
i].nLocks < locallock->nLocks)
2529 if (i < locallock->numLockOwners)
2565 if (locallocks == NULL)
2579 for (
i = nlocks - 1;
i >= 0;
i--)
2605 else if (lockOwners[
i].owner == parent)
2615 lockOwners[ic].
owner = parent;
2624 if (ic < locallock->numLockOwners)
2675 bool result =
false;
2762 hashcode, lockmode);
2810 lockmode = locallock->
tag.
mode;
2824 (
errcode(ERRCODE_OUT_OF_MEMORY),
2825 errmsg(
"out of shared memory"),
2826 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
2840 if (proclock == NULL)
2844 uint32 proclock_hashcode;
2854 elog(
ERROR,
"failed to re-find shared lock object");
2856 proclocktag.
myLock = lock;
2867 elog(
ERROR,
"failed to re-find shared proclock object");
2909 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2911 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
2912 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
2935 conflictMask = lockMethodTable->
conflictTab[lockmode];
2988 if (relid != proc->
fpRelId[f])
2999 if ((lockmask & conflictMask) == 0)
3006 vxids[count++] = vxid;
3051 if (conflictMask & proclock->
holdMask)
3067 for (
i = 0;
i < fast_count; ++
i)
3070 if (
i >= fast_count)
3071 vxids[count++] = vxid;
3081 elog(
PANIC,
"too many conflicting locks found");
3104 bool decrement_strong_lock_count)
3110 uint32 proclock_hashcode;
3128 elog(
PANIC,
"failed to re-find shared lock object");
3133 proclocktag.
myLock = lock;
3134 proclocktag.
myProc = proc;
3144 elog(
PANIC,
"failed to re-find shared proclock object");
3162 wakeupNeeded =
UnGrantLock(lock, lockmode, proclock, lockMethodTable);
3165 lockMethodTable, hashcode,
3173 if (decrement_strong_lock_count
3222 hash_ctl.
entrysize =
sizeof(PerLockTagEntry);
3225 lockhtab =
hash_create(
"CheckForSessionAndXactLocks table",
3236 PerLockTagEntry *hentry;
3248 if (locallock->
nLocks <= 0)
3252 hentry = (PerLockTagEntry *)
hash_search(lockhtab,
3256 hentry->sessLock = hentry->xactLock =
false;
3261 if (lockOwners[
i].owner == NULL)
3262 hentry->sessLock =
true;
3264 hentry->xactLock =
true;
3271 if (hentry->sessLock && hentry->xactLock)
3273 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3274 errmsg(
"cannot PREPARE while holding both session-level and transaction-level locks on the same object")));
3309 bool haveSessionLock;
3321 if (locallock->
nLocks <= 0)
3325 haveSessionLock = haveXactLock =
false;
3328 if (lockOwners[
i].owner == NULL)
3329 haveSessionLock =
true;
3331 haveXactLock =
true;
3339 if (haveSessionLock)
3341 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3342 errmsg(
"cannot PREPARE while holding both session-level and transaction-level locks on the same object")));
3421 bool haveSessionLock;
3425 if (locallock->
proclock == NULL || locallock->
lock == NULL)
3441 haveSessionLock = haveXactLock =
false;
3444 if (lockOwners[
i].owner == NULL)
3445 haveSessionLock =
true;
3447 haveXactLock =
true;
3455 if (haveSessionLock)
3457 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3458 errmsg(
"cannot PREPARE while holding both session-level and transaction-level locks on the same object")));
3461 if (locallock->
nLocks > 0)
3517 elog(
PANIC,
"we seem to have dropped a bit somewhere");
3537 proclocktag.
myLock = lock;
3538 proclocktag.
myProc = newproc;
3555 elog(
PANIC,
"duplicate entry found while reassigning a prepared transaction's locks");
3577 long max_table_size;
3584 max_table_size *= 2;
3662 instance = &
data->locks[el];
3669 instance->
pid = proc->
pid;
3697 instance = &
data->locks[el];
3703 instance->
pid = proc->
pid;
3732 if (
data->nelements > els)
3734 els =
data->nelements;
3756 instance->
pid = proc->
pid;
3893 if (theLock == NULL)
3897 bproc = &
data->procs[
data->nprocs++];
3898 bproc->
pid = blocked_proc->
pid;
3916 if (
data->nlocks >=
data->maxlocks)
3923 instance = &
data->locks[
data->nlocks];
3932 instance->
pid = proc->
pid;
3942 if (queue_size >
data->maxpids -
data->npids)
3945 data->npids + queue_size);
3947 sizeof(
int) *
data->maxpids);
3955 if (queued_proc == blocked_proc)
3957 data->waiter_pids[
data->npids++] = queued_proc->
pid;
4034 accessExclusiveLocks[
index].
xid = xid;
4055 return accessExclusiveLocks;
4129 elog(
LOG,
"DumpAllLocks: proclock->tag.myLock = NULL");
4177 uint32 proclock_hashcode;
4188 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4209 (
errcode(ERRCODE_OUT_OF_MEMORY),
4210 errmsg(
"out of shared memory"),
4211 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
4227 LOCK_PRINT(
"lock_twophase_recover: new", lock, lockmode);
4231 LOCK_PRINT(
"lock_twophase_recover: found", lock, lockmode);
4240 proclocktag.
myLock = lock;
4241 proclocktag.
myProc = proc;
4274 (
errcode(ERRCODE_OUT_OF_MEMORY),
4275 errmsg(
"out of shared memory"),
4276 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
4312 elog(
ERROR,
"lock %s on object %u/%u/%u is already held",
4359 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4391 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4624 (
errcode(ERRCODE_OUT_OF_MEMORY),
4625 errmsg(
"out of shared memory"),
4626 errhint(
"You might need to increase \"%s\".",
"max_locks_per_transaction")));
4671 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
#define Assert(condition)
uint32 LocalTransactionId
#define MemSet(start, val, len)
void DeadLockReport(void)
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)
long hash_get_num_entries(HTAB *hashp)
Size hash_estimate_size(long num_entries, Size entrysize)
bool hash_update_hash_key(HTAB *hashp, void *existingEntry, const void *newKeyPtr)
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
static void dlist_delete(dlist_node *node)
static uint32 dclist_count(const dclist_head *head)
static bool dclist_is_empty(const dclist_head *head)
#define dlist_foreach_modify(iter, lhead)
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_init(dclist_head *head)
#define dlist_container(type, membername, ptr)
#define dclist_foreach(iter, lhead)
static bool XactLockForVirtualXact(VirtualTransactionId vxid, TransactionId xid, bool wait)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
static LOCALLOCK * awaitedLock
static void RemoveLocalLock(LOCALLOCK *locallock)
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp)
static void LockReassignOwner(LOCALLOCK *locallock, ResourceOwner parent)
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode, bool orstronger)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
static const char *const lock_mode_names[]
#define LOCK_PRINT(where, lock, type)
bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2)
static PROCLOCK * SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode)
static PROCLOCK * FastPathGetRelationLockEntry(LOCALLOCK *locallock)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
#define FastPathStrongLockHashPartition(hashcode)
static uint32 ProcLockHashCode(const PROCLOCKTAG *proclocktag, uint32 hashcode)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
#define FAST_PATH_CHECK_LOCKMODE(proc, n, l)
void GrantAwaitedLock(void)
int LockWaiterCount(const LOCKTAG *locktag)
void AtPrepare_Locks(void)
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void lock_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len)
#define FAST_PATH_LOCKNUMBER_OFFSET
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
void VirtualXactLockTableCleanup(void)
BlockedProcsData * GetBlockerStatusData(int blocked_pid)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
static volatile FastPathStrongRelationLockData * FastPathStrongRelationLocks
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
static void CheckAndSetLockHeld(LOCALLOCK *locallock, bool acquired)
#define ConflictsWithRelationFastPath(locktag, mode)
static bool FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag, uint32 hashcode)
static HTAB * LockMethodLocalHash
void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)
static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode, PROCLOCK *proclock, LockMethod lockMethodTable)
static void WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner, bool dontWait)
#define FAST_PATH_SET_LOCKMODE(proc, n, l)
#define PROCLOCK_PRINT(where, proclockP)
LockData * GetLockStatusData(void)
static void CleanUpLock(LOCK *lock, PROCLOCK *proclock, LockMethod lockMethodTable, uint32 hashcode, bool wakeupNeeded)
static uint32 proclock_hash(const void *key, Size keysize)
static bool FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode)
void AbortStrongLockAcquire(void)
static bool FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode)
static HTAB * LockMethodLockHash
static ResourceOwner awaitedOwner
void lock_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len)
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
#define FAST_PATH_CLEAR_LOCKMODE(proc, n, l)
static const LockMethod LockMethods[]
void lock_twophase_standby_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)
void lock_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
void LockReleaseSession(LOCKMETHODID lockmethodid)
void MarkLockClear(LOCALLOCK *locallock)
static bool IsRelationExtensionLockHeld PG_USED_FOR_ASSERTS_ONLY
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
static const LockMethodData default_lockmethod
#define FAST_PATH_GET_BITS(proc, n)
static LOCALLOCK * StrongLockInProgress
#define FAST_PATH_BITS_PER_SLOT
static const LockMethodData user_lockmethod
static int FastPathLocalUseCount
#define EligibleForRelationFastPath(locktag, mode)
uint32 LockTagHashCode(const LOCKTAG *locktag)
static void BeginStrongLockAcquire(LOCALLOCK *locallock, uint32 fasthashcode)
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
static void GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner)
static const LOCKMASK LockConflicts[]
static void ReleaseLockIfHeld(LOCALLOCK *locallock, bool sessionLock)
LockMethod GetLocksMethodTable(const LOCK *lock)
static void FinishStrongLockAcquire(void)
#define FAST_PATH_STRONG_LOCK_HASH_PARTITIONS
void PostPrepare_Locks(TransactionId xid)
static void LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc, LOCKTAG *locktag, LOCKMODE lockmode, bool decrement_strong_lock_count)
static void CheckForSessionAndXactLocks(void)
static HTAB * LockMethodProcLockHash
struct TwoPhaseLockRecord TwoPhaseLockRecord
LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)
#define DEFAULT_LOCKMETHOD
struct LOCALLOCK LOCALLOCK
#define LOCK_LOCKTAG(lock)
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag, vxid)
@ LOCKTAG_RELATION_EXTEND
@ LOCKTAG_VIRTUALTRANSACTION
#define VirtualTransactionIdIsValid(vxid)
#define LockHashPartitionLock(hashcode)
#define GET_VXID_FROM_PGPROC(vxid_dst, proc)
#define LOCK_LOCKMETHOD(lock)
#define LOCKBIT_OFF(lockmode)
#define LOCALLOCK_LOCKMETHOD(llock)
#define InvalidLocalTransactionId
#define SET_LOCKTAG_TRANSACTION(locktag, xid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
struct PROCLOCKTAG PROCLOCKTAG
#define LOCKBIT_ON(lockmode)
#define LocalTransactionIdIsValid(lxid)
#define LOCALLOCK_LOCKTAG(llock)
#define LockHashPartition(hashcode)
#define VirtualTransactionIdEquals(vxid1, vxid2)
struct LOCALLOCKTAG LOCALLOCKTAG
#define PROCLOCK_LOCKMETHOD(proclock)
#define LockHashPartitionLockByIndex(i)
@ LOCKACQUIRE_ALREADY_CLEAR
@ LOCKACQUIRE_ALREADY_HELD
#define VirtualTransactionIdIsRecoveredPreparedXact(vxid)
#define AccessExclusiveLock
#define ShareRowExclusiveLock
#define ShareUpdateExclusiveLock
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
#define NUM_LOCK_PARTITIONS
#define LOG2_NUM_LOCK_PARTITIONS
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void * MemoryContextAlloc(MemoryContext context, Size size)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
static PgChecksumMode mode
static Datum PointerGetDatum(const void *X)
#define FP_LOCK_SLOTS_PER_BACKEND
@ PROC_WAIT_STATUS_WAITING
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
PGPROC * BackendPidGetProcWithLock(int pid)
#define INVALID_PROC_NUMBER
void set_ps_display_remove_suffix(void)
void set_ps_display_suffix(const char *suffix)
void ResourceOwnerRememberLock(ResourceOwner owner, LOCALLOCK *locallock)
ResourceOwner ResourceOwnerGetParent(ResourceOwner owner)
ResourceOwner CurrentResourceOwner
void ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock)
Size add_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
HTAB * ShmemInitHash(const char *name, long init_size, long max_size, HASHCTL *infoP, int hash_flags)
static pg_noinline void Size size
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
ProcWaitStatus ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
void LogAccessExclusiveLockPrepare(void)
void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]
struct ResourceOwnerData * owner
LOCALLOCKOWNER * lockOwners
bool holdsStrongLockCount
uint8 locktag_lockmethodid
int requested[MAX_LOCKMODES]
int granted[MAX_LOCKMODES]
VirtualTransactionId vxid
const LOCKMASK * conflictTab
const char *const * lockModeNames
Oid fpRelId[FP_LOCK_SLOTS_PER_BACKEND]
dlist_head lockGroupMembers
pg_atomic_uint64 waitStart
LocalTransactionId fpLocalTransactionId
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
ProcWaitStatus waitStatus
LocalTransactionId localTransactionId
#define InvalidTransactionId
#define FirstNormalObjectId
#define TransactionIdIsValid(xid)
void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, const void *data, uint32 len)
TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid, bool *have_more)
PGPROC * TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
#define TWOPHASE_RM_LOCK_ID
bool RecoveryInProgress(void)
#define XLogStandbyInfoActive()
static struct link * links