1 /*-------------------------------------------------------------------------
4 * POSTGRES primary lock mechanism
6 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.168 2006/07/23 23:08:46 tgl Exp $
14 * A lock table is a shared memory hash table. When
15 * a process tries to acquire a lock of a type that conflicts
16 * with existing locks, it is put to sleep using the routines
17 * in storage/lmgr/proc.c.
19 * For the most part, this code should be invoked via lmgr.c
20 * or another lock-management module, not directly.
24 * InitLocks(), GetLocksMethodTable(),
25 * LockAcquire(), LockRelease(), LockReleaseAll(),
26 * LockCheckConflicts(), GrantLock()
28 *-------------------------------------------------------------------------
35 #include "access/transam.h"
36 #include "access/twophase.h"
37 #include "access/twophase_rmgr.h"
38 #include "miscadmin.h"
39 #include "utils/memutils.h"
40 #include "utils/ps_status.h"
41 #include "utils/resowner.h"
44 /* This configuration variable is used to set the lock table size */
45 int max_locks_per_xact; /* set by guc.c */
48 mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
52 * Data structures defining the semantics of the standard lock methods.
54 * The conflict table defines the semantics of the various lock modes.
56 static const LOCKMASK LockConflicts[] = {
60 (1 << AccessExclusiveLock),
63 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
65 /* RowExclusiveLock */
66 (1 << ShareLock) | (1 << ShareRowExclusiveLock) |
67 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
69 /* ShareUpdateExclusiveLock */
70 (1 << ShareUpdateExclusiveLock) |
71 (1 << ShareLock) | (1 << ShareRowExclusiveLock) |
72 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
75 (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) |
76 (1 << ShareRowExclusiveLock) |
77 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
79 /* ShareRowExclusiveLock */
80 (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) |
81 (1 << ShareLock) | (1 << ShareRowExclusiveLock) |
82 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
86 (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) |
87 (1 << ShareLock) | (1 << ShareRowExclusiveLock) |
88 (1 << ExclusiveLock) | (1 << AccessExclusiveLock),
90 /* AccessExclusiveLock */
91 (1 << AccessShareLock) | (1 << RowShareLock) |
92 (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) |
93 (1 << ShareLock) | (1 << ShareRowExclusiveLock) |
94 (1 << ExclusiveLock) | (1 << AccessExclusiveLock)
98 /* Names of lock modes, for debug printouts */
99 static const char *const lock_mode_names[] =
105 "ShareUpdateExclusiveLock",
107 "ShareRowExclusiveLock",
109 "AccessExclusiveLock"
113 static bool Dummy_trace = false;
116 static const LockMethodData default_lockmethod = {
117 AccessExclusiveLock, /* highest valid lock mode number */
130 static const LockMethodData user_lockmethod = {
131 AccessExclusiveLock, /* highest valid lock mode number */
142 #endif /* USER_LOCKS */
145 * map from lock method id to the lock table data structures
147 static const LockMethod LockMethods[] = {
156 /* Record that's written to 2PC state file when a lock is persisted */
157 typedef struct TwoPhaseLockRecord
161 } TwoPhaseLockRecord;
165 * Pointers to hash tables containing lock state
167 * The LockMethodLockHash and LockMethodProcLockHash hash tables are in
168 * shared memory; LockMethodLocalHash is local to each backend.
170 static HTAB *LockMethodLockHash;
171 static HTAB *LockMethodProcLockHash;
172 static HTAB *LockMethodLocalHash;
175 /* private state for GrantAwaitedLock */
176 static LOCALLOCK *awaitedLock;
177 static ResourceOwner awaitedOwner;
183 * The following configuration options are available for lock debugging:
185 * TRACE_LOCKS -- give a bunch of output what's going on in this file
186 * TRACE_USERLOCKS -- same but for user locks
187 * TRACE_LOCK_OIDMIN-- do not trace locks for tables below this oid
188 * (use to avoid output on system tables)
189 * TRACE_LOCK_TABLE -- trace locks on this table (oid) unconditionally
190 * DEBUG_DEADLOCKS -- currently dumps locks at untimely occasions ;)
192 * Furthermore, but in storage/lmgr/lwlock.c:
193 * TRACE_LWLOCKS -- trace lightweight locks (pretty useless)
195 * Define LOCK_DEBUG at compile time to get all these enabled.
199 int Trace_lock_oidmin = FirstNormalObjectId;
200 bool Trace_locks = false;
201 bool Trace_userlocks = false;
202 int Trace_lock_table = 0;
203 bool Debug_deadlocks = false;
207 LOCK_DEBUG_ENABLED(const LOCKTAG *tag)
210 (*(LockMethods[tag->locktag_lockmethodid]->trace_flag) &&
211 ((Oid) tag->locktag_field2 >= (Oid) Trace_lock_oidmin))
212 || (Trace_lock_table &&
213 (tag->locktag_field2 == Trace_lock_table));
218 LOCK_PRINT(const char *where, const LOCK *lock, LOCKMODE type)
220 if (LOCK_DEBUG_ENABLED(&lock->tag))
222 "%s: lock(%p) id(%u,%u,%u,%u,%u,%u) grantMask(%x) "
223 "req(%d,%d,%d,%d,%d,%d,%d)=%d "
224 "grant(%d,%d,%d,%d,%d,%d,%d)=%d wait(%d) type(%s)",
226 lock->tag.locktag_field1, lock->tag.locktag_field2,
227 lock->tag.locktag_field3, lock->tag.locktag_field4,
228 lock->tag.locktag_type, lock->tag.locktag_lockmethodid,
230 lock->requested[1], lock->requested[2], lock->requested[3],
231 lock->requested[4], lock->requested[5], lock->requested[6],
232 lock->requested[7], lock->nRequested,
233 lock->granted[1], lock->granted[2], lock->granted[3],
234 lock->granted[4], lock->granted[5], lock->granted[6],
235 lock->granted[7], lock->nGranted,
236 lock->waitProcs.size,
237 LockMethods[LOCK_LOCKMETHOD(*lock)]->lockModeNames[type]);
242 PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP)
244 if (LOCK_DEBUG_ENABLED(&proclockP->tag.myLock->tag))
246 "%s: proclock(%p) lock(%p) method(%u) proc(%p) hold(%x)",
247 where, proclockP, proclockP->tag.myLock,
248 PROCLOCK_LOCKMETHOD(*(proclockP)),
249 proclockP->tag.myProc, (int) proclockP->holdMask);
251 #else /* not LOCK_DEBUG */
253 #define LOCK_PRINT(where, lock, type)
254 #define PROCLOCK_PRINT(where, proclockP)
255 #endif /* not LOCK_DEBUG */
258 static uint32 proclock_hash(const void *key, Size keysize);
259 static void RemoveLocalLock(LOCALLOCK *locallock);
260 static void GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner);
261 static void WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner);
262 static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode,
263 PROCLOCK *proclock, LockMethod lockMethodTable);
264 static void CleanUpLock(LOCK *lock, PROCLOCK *proclock,
265 LockMethod lockMethodTable, uint32 hashcode,
270 * InitLocks -- Initialize the lock manager's data structures.
272 * This is called from CreateSharedMemoryAndSemaphores(), which see for
273 * more comments. In the normal postmaster case, the shared hash tables
274 * are created here, as well as a locallock hash table that will remain
275 * unused and empty in the postmaster itself. Backends inherit the pointers
276 * to the shared tables via fork(), and also inherit an image of the locallock
277 * hash table, which they proceed to use. In the EXEC_BACKEND case, each
278 * backend re-executes this code to obtain pointers to the already existing
279 * shared hash tables and to create its locallock hash table.
286 long init_table_size,
290 * Compute init/max size to request for lock hashtables. Note these
291 * calculations must agree with LockShmemSize!
293 max_table_size = NLOCKENTS();
294 init_table_size = max_table_size / 2;
297 * Allocate hash table for LOCK structs. This stores
298 * per-locked-object information.
300 MemSet(&info, 0, sizeof(info));
301 info.keysize = sizeof(LOCKTAG);
302 info.entrysize = sizeof(LOCK);
303 info.hash = tag_hash;
304 info.num_partitions = NUM_LOCK_PARTITIONS;
305 hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
307 LockMethodLockHash = ShmemInitHash("LOCK hash",
312 if (!LockMethodLockHash)
313 elog(FATAL, "could not initialize lock hash table");
315 /* Assume an average of 2 holders per lock */
317 init_table_size *= 2;
320 * Allocate hash table for PROCLOCK structs. This stores
321 * per-lock-per-holder information.
323 info.keysize = sizeof(PROCLOCKTAG);
324 info.entrysize = sizeof(PROCLOCK);
325 info.hash = proclock_hash;
326 info.num_partitions = NUM_LOCK_PARTITIONS;
327 hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
329 LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash",
334 if (!LockMethodProcLockHash)
335 elog(FATAL, "could not initialize proclock hash table");
338 * Allocate non-shared hash table for LOCALLOCK structs. This stores
339 * lock counts and resource owner information.
341 * The non-shared table could already exist in this process (this occurs
342 * when the postmaster is recreating shared memory after a backend crash).
343 * If so, delete and recreate it. (We could simply leave it, since it
344 * ought to be empty in the postmaster, but for safety let's zap it.)
346 if (LockMethodLocalHash)
347 hash_destroy(LockMethodLocalHash);
349 info.keysize = sizeof(LOCALLOCKTAG);
350 info.entrysize = sizeof(LOCALLOCK);
351 info.hash = tag_hash;
352 hash_flags = (HASH_ELEM | HASH_FUNCTION);
354 LockMethodLocalHash = hash_create("LOCALLOCK hash",
362 * Fetch the lock method table associated with a given lock
365 GetLocksMethodTable(const LOCK *lock)
367 LOCKMETHODID lockmethodid = LOCK_LOCKMETHOD(*lock);
369 Assert(0 < lockmethodid && lockmethodid < lengthof(LockMethods));
370 return LockMethods[lockmethodid];
375 * Compute the hash code associated with a LOCKTAG.
377 * To avoid unnecessary recomputations of the hash code, we try to do this
378 * just once per function, and then pass it around as needed. Aside from
379 * passing the hashcode to hash_search_with_hash_value(), we can extract
380 * the lock partition number from the hashcode.
383 LockTagHashCode(const LOCKTAG *locktag)
385 return get_hash_value(LockMethodLockHash, (const void *) locktag);
389 * Compute the hash code associated with a PROCLOCKTAG.
391 * Because we want to use just one set of partition locks for both the
392 * LOCK and PROCLOCK hash tables, we have to make sure that PROCLOCKs
393 * fall into the same partition number as their associated LOCKs.
394 * dynahash.c expects the partition number to be the low-order bits of
395 * the hash code, and therefore a PROCLOCKTAG's hash code must have the
396 * same low-order bits as the associated LOCKTAG's hash code. We achieve
397 * this with this specialized hash function.
400 proclock_hash(const void *key, Size keysize)
402 const PROCLOCKTAG *proclocktag = (const PROCLOCKTAG *) key;
406 Assert(keysize == sizeof(PROCLOCKTAG));
408 /* Look into the associated LOCK object, and compute its hash code */
409 lockhash = LockTagHashCode(&proclocktag->myLock->tag);
412 * To make the hash code also depend on the PGPROC, we xor the proc
413 * struct's address into the hash code, left-shifted so that the
414 * partition-number bits don't change. Since this is only a hash,
415 * we don't care if we lose high-order bits of the address; use
416 * an intermediate variable to suppress cast-pointer-to-int warnings.
418 procptr = PointerGetDatum(proclocktag->myProc);
419 lockhash ^= ((uint32) procptr) << LOG2_NUM_LOCK_PARTITIONS;
425 * Compute the hash code associated with a PROCLOCKTAG, given the hashcode
426 * for its underlying LOCK.
428 * We use this just to avoid redundant calls of LockTagHashCode().
431 ProcLockHashCode(const PROCLOCKTAG *proclocktag, uint32 hashcode)
433 uint32 lockhash = hashcode;
437 * This must match proclock_hash()!
439 procptr = PointerGetDatum(proclocktag->myProc);
440 lockhash ^= ((uint32) procptr) << LOG2_NUM_LOCK_PARTITIONS;
447 * LockAcquire -- Check for lock conflicts, sleep if conflict found,
448 * set lock if/when no conflicts.
451 * locktag: unique identifier for the lockable object
452 * isTempObject: is the lockable object a temporary object? (Under 2PC,
453 * such locks cannot be persisted)
454 * lockmode: lock mode to acquire
455 * sessionLock: if true, acquire lock for session not current transaction
456 * dontWait: if true, don't wait to acquire lock
459 * LOCKACQUIRE_NOT_AVAIL lock not available, and dontWait=true
460 * LOCKACQUIRE_OK lock successfully acquired
461 * LOCKACQUIRE_ALREADY_HELD incremented count for lock already held
463 * In the normal case where dontWait=false and the caller doesn't need to
464 * distinguish a freshly acquired lock from one already taken earlier in
465 * this same transaction, there is no need to examine the return value.
467 * Side Effects: The lock is acquired and recorded in lock tables.
469 * NOTE: if we wait for the lock, there is no way to abort the wait
470 * short of aborting the transaction.
473 LockAcquire(const LOCKTAG *locktag,
479 LOCKMETHODID lockmethodid = locktag->locktag_lockmethodid;
480 LockMethod lockMethodTable;
481 LOCALLOCKTAG localtag;
482 LOCALLOCK *locallock;
485 PROCLOCKTAG proclocktag;
489 uint32 proclock_hashcode;
491 LWLockId partitionLock;
494 if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
495 elog(ERROR, "unrecognized lock method: %d", lockmethodid);
496 lockMethodTable = LockMethods[lockmethodid];
497 if (lockmode <= 0 || lockmode > lockMethodTable->numLockModes)
498 elog(ERROR, "unrecognized lock mode: %d", lockmode);
501 if (LOCK_DEBUG_ENABLED(locktag))
502 elog(LOG, "LockAcquire: lock [%u,%u] %s",
503 locktag->locktag_field1, locktag->locktag_field2,
504 lockMethodTable->lockModeNames[lockmode]);
507 /* Session locks are never transactional, else check table */
508 if (!sessionLock && lockMethodTable->transactional)
509 owner = CurrentResourceOwner;
514 * Find or create a LOCALLOCK entry for this lock and lockmode
516 MemSet(&localtag, 0, sizeof(localtag)); /* must clear padding */
517 localtag.lock = *locktag;
518 localtag.mode = lockmode;
520 locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
525 * if it's a new locallock object, initialize it
529 locallock->lock = NULL;
530 locallock->proclock = NULL;
531 locallock->isTempObject = isTempObject;
532 locallock->hashcode = LockTagHashCode(&(localtag.lock));
533 locallock->nLocks = 0;
534 locallock->numLockOwners = 0;
535 locallock->maxLockOwners = 8;
536 locallock->lockOwners = NULL;
537 locallock->lockOwners = (LOCALLOCKOWNER *)
538 MemoryContextAlloc(TopMemoryContext,
539 locallock->maxLockOwners * sizeof(LOCALLOCKOWNER));
543 Assert(locallock->isTempObject == isTempObject);
545 /* Make sure there will be room to remember the lock */
546 if (locallock->numLockOwners >= locallock->maxLockOwners)
548 int newsize = locallock->maxLockOwners * 2;
550 locallock->lockOwners = (LOCALLOCKOWNER *)
551 repalloc(locallock->lockOwners,
552 newsize * sizeof(LOCALLOCKOWNER));
553 locallock->maxLockOwners = newsize;
558 * If we already hold the lock, we can just increase the count locally.
560 if (locallock->nLocks > 0)
562 GrantLockLocal(locallock, owner);
563 return LOCKACQUIRE_ALREADY_HELD;
567 * Otherwise we've got to mess with the shared lock table.
569 hashcode = locallock->hashcode;
570 partition = LockHashPartition(hashcode);
571 partitionLock = LockHashPartitionLock(hashcode);
573 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
576 * Find or create a lock with this tag.
578 * Note: if the locallock object already existed, it might have a pointer
579 * to the lock already ... but we probably should not assume that that
580 * pointer is valid, since a lock object with no locks can go away
583 lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
590 LWLockRelease(partitionLock);
592 (errcode(ERRCODE_OUT_OF_MEMORY),
593 errmsg("out of shared memory"),
594 errhint("You may need to increase max_locks_per_transaction.")));
596 locallock->lock = lock;
599 * if it's a new lock object, initialize it
605 SHMQueueInit(&(lock->procLocks));
606 ProcQueueInit(&(lock->waitProcs));
607 lock->nRequested = 0;
609 MemSet(lock->requested, 0, sizeof(int) * MAX_LOCKMODES);
610 MemSet(lock->granted, 0, sizeof(int) * MAX_LOCKMODES);
611 LOCK_PRINT("LockAcquire: new", lock, lockmode);
615 LOCK_PRINT("LockAcquire: found", lock, lockmode);
616 Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
617 Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
618 Assert(lock->nGranted <= lock->nRequested);
622 * Create the hash key for the proclock table.
624 proclocktag.myLock = lock;
625 proclocktag.myProc = MyProc;
627 proclock_hashcode = ProcLockHashCode(&proclocktag, hashcode);
630 * Find or create a proclock entry with this tag
632 proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
633 (void *) &proclocktag,
639 /* Ooops, not enough shmem for the proclock */
640 if (lock->nRequested == 0)
643 * There are no other requestors of this lock, so garbage-collect
644 * the lock object. We *must* do this to avoid a permanent leak
645 * of shared memory, because there won't be anything to cause
646 * anyone to release the lock object later.
648 Assert(SHMQueueEmpty(&(lock->procLocks)));
649 if (!hash_search_with_hash_value(LockMethodLockHash,
650 (void *) &(lock->tag),
654 elog(PANIC, "lock table corrupted");
656 LWLockRelease(partitionLock);
658 (errcode(ERRCODE_OUT_OF_MEMORY),
659 errmsg("out of shared memory"),
660 errhint("You may need to increase max_locks_per_transaction.")));
662 locallock->proclock = proclock;
665 * If new, initialize the new entry
669 proclock->holdMask = 0;
670 proclock->releaseMask = 0;
671 /* Add proclock to appropriate lists */
672 SHMQueueInsertBefore(&lock->procLocks, &proclock->lockLink);
673 SHMQueueInsertBefore(&(MyProc->myProcLocks[partition]),
674 &proclock->procLink);
675 PROCLOCK_PRINT("LockAcquire: new", proclock);
679 PROCLOCK_PRINT("LockAcquire: found", proclock);
680 Assert((proclock->holdMask & ~lock->grantMask) == 0);
682 #ifdef CHECK_DEADLOCK_RISK
685 * Issue warning if we already hold a lower-level lock on this object
686 * and do not hold a lock of the requested level or higher. This
687 * indicates a deadlock-prone coding practice (eg, we'd have a
688 * deadlock if another backend were following the same code path at
689 * about the same time).
691 * This is not enabled by default, because it may generate log entries
692 * about user-level coding practices that are in fact safe in context.
693 * It can be enabled to help find system-level problems.
695 * XXX Doing numeric comparison on the lockmodes is a hack; it'd be
696 * better to use a table. For now, though, this works.
701 for (i = lockMethodTable->numLockModes; i > 0; i--)
703 if (proclock->holdMask & LOCKBIT_ON(i))
705 if (i >= (int) lockmode)
706 break; /* safe: we have a lock >= req level */
707 elog(LOG, "deadlock risk: raising lock level"
708 " from %s to %s on object %u/%u/%u",
709 lockMethodTable->lockModeNames[i],
710 lockMethodTable->lockModeNames[lockmode],
711 lock->tag.locktag_field1, lock->tag.locktag_field2,
712 lock->tag.locktag_field3);
717 #endif /* CHECK_DEADLOCK_RISK */
721 * lock->nRequested and lock->requested[] count the total number of
722 * requests, whether granted or waiting, so increment those immediately.
723 * The other counts don't increment till we get the lock.
726 lock->requested[lockmode]++;
727 Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
730 * We shouldn't already hold the desired lock; else locallock table is
733 if (proclock->holdMask & LOCKBIT_ON(lockmode))
734 elog(ERROR, "lock %s on object %u/%u/%u is already held",
735 lockMethodTable->lockModeNames[lockmode],
736 lock->tag.locktag_field1, lock->tag.locktag_field2,
737 lock->tag.locktag_field3);
740 * If lock requested conflicts with locks requested by waiters, must join
741 * wait queue. Otherwise, check for conflict with already-held locks.
742 * (That's last because most complex check.)
744 if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
745 status = STATUS_FOUND;
747 status = LockCheckConflicts(lockMethodTable, lockmode,
748 lock, proclock, MyProc);
750 if (status == STATUS_OK)
752 /* No conflict with held or previously requested locks */
753 GrantLock(lock, proclock, lockmode);
754 GrantLockLocal(locallock, owner);
758 Assert(status == STATUS_FOUND);
761 * We can't acquire the lock immediately. If caller specified no
762 * blocking, remove useless table entries and return NOT_AVAIL without
767 if (proclock->holdMask == 0)
769 SHMQueueDelete(&proclock->lockLink);
770 SHMQueueDelete(&proclock->procLink);
771 if (!hash_search_with_hash_value(LockMethodProcLockHash,
772 (void *) &(proclock->tag),
776 elog(PANIC, "proclock table corrupted");
779 PROCLOCK_PRINT("LockAcquire: NOWAIT", proclock);
781 lock->requested[lockmode]--;
782 LOCK_PRINT("LockAcquire: conditional lock failed", lock, lockmode);
783 Assert((lock->nRequested > 0) && (lock->requested[lockmode] >= 0));
784 Assert(lock->nGranted <= lock->nRequested);
785 LWLockRelease(partitionLock);
786 if (locallock->nLocks == 0)
787 RemoveLocalLock(locallock);
788 return LOCKACQUIRE_NOT_AVAIL;
792 * Set bitmask of locks this process already holds on this object.
794 MyProc->heldLocks = proclock->holdMask;
797 * Sleep till someone wakes me up.
799 WaitOnLock(locallock, owner);
802 * NOTE: do not do any material change of state between here and
803 * return. All required changes in locktable state must have been
804 * done when the lock was granted to us --- see notes in WaitOnLock.
808 * Check the proclock entry status, in case something in the ipc
809 * communication doesn't work correctly.
811 if (!(proclock->holdMask & LOCKBIT_ON(lockmode)))
813 PROCLOCK_PRINT("LockAcquire: INCONSISTENT", proclock);
814 LOCK_PRINT("LockAcquire: INCONSISTENT", lock, lockmode);
815 /* Should we retry ? */
816 LWLockRelease(partitionLock);
817 elog(ERROR, "LockAcquire failed");
819 PROCLOCK_PRINT("LockAcquire: granted", proclock);
820 LOCK_PRINT("LockAcquire: granted", lock, lockmode);
823 LWLockRelease(partitionLock);
825 return LOCKACQUIRE_OK;
829 * Subroutine to free a locallock entry
832 RemoveLocalLock(LOCALLOCK *locallock)
834 pfree(locallock->lockOwners);
835 locallock->lockOwners = NULL;
836 if (!hash_search(LockMethodLocalHash,
837 (void *) &(locallock->tag),
839 elog(WARNING, "locallock table corrupted");
843 * LockCheckConflicts -- test whether requested lock conflicts
844 * with those already granted
846 * Returns STATUS_FOUND if conflict, STATUS_OK if no conflict.
849 * Here's what makes this complicated: one process's locks don't
850 * conflict with one another, no matter what purpose they are held for
851 * (eg, session and transaction locks do not conflict).
852 * So, we must subtract off our own locks when determining whether the
853 * requested new lock conflicts with those already held.
856 LockCheckConflicts(LockMethod lockMethodTable,
862 int numLockModes = lockMethodTable->numLockModes;
868 * first check for global conflicts: If no locks conflict with my request,
869 * then I get the lock.
871 * Checking for conflict: lock->grantMask represents the types of
872 * currently held locks. conflictTable[lockmode] has a bit set for each
873 * type of lock that conflicts with request. Bitwise compare tells if
874 * there is a conflict.
876 if (!(lockMethodTable->conflictTab[lockmode] & lock->grantMask))
878 PROCLOCK_PRINT("LockCheckConflicts: no conflict", proclock);
883 * Rats. Something conflicts. But it could still be my own lock. We have
884 * to construct a conflict mask that does not reflect our own locks, but
885 * only lock types held by other processes.
887 myLocks = proclock->holdMask;
889 for (i = 1; i <= numLockModes; i++)
891 int myHolding = (myLocks & LOCKBIT_ON(i)) ? 1 : 0;
893 if (lock->granted[i] > myHolding)
894 otherLocks |= LOCKBIT_ON(i);
898 * now check again for conflicts. 'otherLocks' describes the types of
899 * locks held by other processes. If one of these conflicts with the kind
900 * of lock that I want, there is a conflict and I have to sleep.
902 if (!(lockMethodTable->conflictTab[lockmode] & otherLocks))
904 /* no conflict. OK to get the lock */
905 PROCLOCK_PRINT("LockCheckConflicts: resolved", proclock);
909 PROCLOCK_PRINT("LockCheckConflicts: conflicting", proclock);
914 * GrantLock -- update the lock and proclock data structures to show
915 * the lock request has been granted.
917 * NOTE: if proc was blocked, it also needs to be removed from the wait list
918 * and have its waitLock/waitProcLock fields cleared. That's not done here.
920 * NOTE: the lock grant also has to be recorded in the associated LOCALLOCK
921 * table entry; but since we may be awaking some other process, we can't do
922 * that here; it's done by GrantLockLocal, instead.
925 GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
928 lock->granted[lockmode]++;
929 lock->grantMask |= LOCKBIT_ON(lockmode);
930 if (lock->granted[lockmode] == lock->requested[lockmode])
931 lock->waitMask &= LOCKBIT_OFF(lockmode);
932 proclock->holdMask |= LOCKBIT_ON(lockmode);
933 LOCK_PRINT("GrantLock", lock, lockmode);
934 Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
935 Assert(lock->nGranted <= lock->nRequested);
939 * UnGrantLock -- opposite of GrantLock.
941 * Updates the lock and proclock data structures to show that the lock
942 * is no longer held nor requested by the current holder.
944 * Returns true if there were any waiters waiting on the lock that
945 * should now be woken up with ProcLockWakeup.
948 UnGrantLock(LOCK *lock, LOCKMODE lockmode,
949 PROCLOCK *proclock, LockMethod lockMethodTable)
951 bool wakeupNeeded = false;
953 Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
954 Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
955 Assert(lock->nGranted <= lock->nRequested);
958 * fix the general lock stats
961 lock->requested[lockmode]--;
963 lock->granted[lockmode]--;
965 if (lock->granted[lockmode] == 0)
967 /* change the conflict mask. No more of this lock type. */
968 lock->grantMask &= LOCKBIT_OFF(lockmode);
971 LOCK_PRINT("UnGrantLock: updated", lock, lockmode);
974 * We need only run ProcLockWakeup if the released lock conflicts with at
975 * least one of the lock types requested by waiter(s). Otherwise whatever
976 * conflict made them wait must still exist. NOTE: before MVCC, we could
977 * skip wakeup if lock->granted[lockmode] was still positive. But that's
978 * not true anymore, because the remaining granted locks might belong to
979 * some waiter, who could now be awakened because he doesn't conflict with
982 if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
986 * Now fix the per-proclock state.
988 proclock->holdMask &= LOCKBIT_OFF(lockmode);
989 PROCLOCK_PRINT("UnGrantLock: updated", proclock);
995 * CleanUpLock -- clean up after releasing a lock. We garbage-collect the
996 * proclock and lock objects if possible, and call ProcLockWakeup if there
997 * are remaining requests and the caller says it's OK. (Normally, this
998 * should be called after UnGrantLock, and wakeupNeeded is the result from
1001 * The appropriate partition lock must be held at entry, and will be
1005 CleanUpLock(LOCK *lock, PROCLOCK *proclock,
1006 LockMethod lockMethodTable, uint32 hashcode,
1010 * If this was my last hold on this lock, delete my entry in the proclock
1013 if (proclock->holdMask == 0)
1015 uint32 proclock_hashcode;
1017 PROCLOCK_PRINT("CleanUpLock: deleting", proclock);
1018 SHMQueueDelete(&proclock->lockLink);
1019 SHMQueueDelete(&proclock->procLink);
1020 proclock_hashcode = ProcLockHashCode(&proclock->tag, hashcode);
1021 if (!hash_search_with_hash_value(LockMethodProcLockHash,
1022 (void *) &(proclock->tag),
1026 elog(PANIC, "proclock table corrupted");
1029 if (lock->nRequested == 0)
1032 * The caller just released the last lock, so garbage-collect the lock
1035 LOCK_PRINT("CleanUpLock: deleting", lock, 0);
1036 Assert(SHMQueueEmpty(&(lock->procLocks)));
1037 if (!hash_search_with_hash_value(LockMethodLockHash,
1038 (void *) &(lock->tag),
1042 elog(PANIC, "lock table corrupted");
1044 else if (wakeupNeeded)
1046 /* There are waiters on this lock, so wake them up. */
1047 ProcLockWakeup(lockMethodTable, lock);
1052 * GrantLockLocal -- update the locallock data structures to show
1053 * the lock request has been granted.
1055 * We expect that LockAcquire made sure there is room to add a new
1056 * ResourceOwner entry.
1059 GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner)
1061 LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
1064 Assert(locallock->numLockOwners < locallock->maxLockOwners);
1065 /* Count the total */
1066 locallock->nLocks++;
1067 /* Count the per-owner lock */
1068 for (i = 0; i < locallock->numLockOwners; i++)
1070 if (lockOwners[i].owner == owner)
1072 lockOwners[i].nLocks++;
1076 lockOwners[i].owner = owner;
1077 lockOwners[i].nLocks = 1;
1078 locallock->numLockOwners++;
1082 * GrantAwaitedLock -- call GrantLockLocal for the lock we are doing
1085 * proc.c needs this for the case where we are booted off the lock by
1086 * timeout, but discover that someone granted us the lock anyway.
1088 * We could just export GrantLockLocal, but that would require including
1089 * resowner.h in lock.h, which creates circularity.
1092 GrantAwaitedLock(void)
1094 GrantLockLocal(awaitedLock, awaitedOwner);
1098 * WaitOnLock -- wait to acquire a lock
1100 * Caller must have set MyProc->heldLocks to reflect locks already held
1101 * on the lockable object by this process.
1103 * The appropriate partition lock must be held at entry.
1106 WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
1108 LOCKMETHODID lockmethodid = LOCALLOCK_LOCKMETHOD(*locallock);
1109 LockMethod lockMethodTable = LockMethods[lockmethodid];
1110 const char *old_status;
1111 char *new_status = NULL;
1114 LOCK_PRINT("WaitOnLock: sleeping on lock",
1115 locallock->lock, locallock->tag.mode);
1117 if (update_process_title)
1119 old_status = get_ps_display(&len);
1120 new_status = (char *) palloc(len + 8 + 1);
1121 memcpy(new_status, old_status, len);
1122 strcpy(new_status + len, " waiting");
1123 set_ps_display(new_status, false);
1124 new_status[len] = '\0'; /* truncate off " waiting" */
1127 awaitedLock = locallock;
1128 awaitedOwner = owner;
1131 * NOTE: Think not to put any shared-state cleanup after the call to
1132 * ProcSleep, in either the normal or failure path. The lock state must
1133 * be fully set by the lock grantor, or by CheckDeadLock if we give up
1134 * waiting for the lock. This is necessary because of the possibility
1135 * that a cancel/die interrupt will interrupt ProcSleep after someone else
1136 * grants us the lock, but before we've noticed it. Hence, after granting,
1137 * the locktable state must fully reflect the fact that we own the lock;
1138 * we can't do additional work on return. Contrariwise, if we fail, any
1139 * cleanup must happen in xact abort processing, not here, to ensure it
1140 * will also happen in the cancel/die case.
1143 if (ProcSleep(locallock, lockMethodTable) != STATUS_OK)
1146 * We failed as a result of a deadlock, see CheckDeadLock(). Quit now.
1149 LOCK_PRINT("WaitOnLock: aborting on lock",
1150 locallock->lock, locallock->tag.mode);
1151 LWLockRelease(LockHashPartitionLock(locallock->hashcode));
1154 * Now that we aren't holding the partition lock, we can give an error
1155 * report including details about the detected deadlock.
1163 if (update_process_title)
1165 set_ps_display(new_status, false);
1169 LOCK_PRINT("WaitOnLock: wakeup on lock",
1170 locallock->lock, locallock->tag.mode);
1174 * Remove a proc from the wait-queue it is on (caller must know it is on one).
1175 * This is only used when the proc has failed to get the lock, so we set its
1176 * waitStatus to STATUS_ERROR.
1178 * Appropriate partition lock must be held by caller. Also, caller is
1179 * responsible for signaling the proc if needed.
1181 * NB: this does not clean up any locallock object that may exist for the lock.
1184 RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
1186 LOCK *waitLock = proc->waitLock;
1187 PROCLOCK *proclock = proc->waitProcLock;
1188 LOCKMODE lockmode = proc->waitLockMode;
1189 LOCKMETHODID lockmethodid = LOCK_LOCKMETHOD(*waitLock);
1191 /* Make sure proc is waiting */
1192 Assert(proc->waitStatus == STATUS_WAITING);
1193 Assert(proc->links.next != INVALID_OFFSET);
1195 Assert(waitLock->waitProcs.size > 0);
1196 Assert(0 < lockmethodid && lockmethodid < lengthof(LockMethods));
1198 /* Remove proc from lock's wait queue */
1199 SHMQueueDelete(&(proc->links));
1200 waitLock->waitProcs.size--;
1202 /* Undo increments of request counts by waiting process */
1203 Assert(waitLock->nRequested > 0);
1204 Assert(waitLock->nRequested > proc->waitLock->nGranted);
1205 waitLock->nRequested--;
1206 Assert(waitLock->requested[lockmode] > 0);
1207 waitLock->requested[lockmode]--;
1208 /* don't forget to clear waitMask bit if appropriate */
1209 if (waitLock->granted[lockmode] == waitLock->requested[lockmode])
1210 waitLock->waitMask &= LOCKBIT_OFF(lockmode);
1212 /* Clean up the proc's own state, and pass it the ok/fail signal */
1213 proc->waitLock = NULL;
1214 proc->waitProcLock = NULL;
1215 proc->waitStatus = STATUS_ERROR;
1218 * Delete the proclock immediately if it represents no already-held locks.
1219 * (This must happen now because if the owner of the lock decides to
1220 * release it, and the requested/granted counts then go to zero,
1221 * LockRelease expects there to be no remaining proclocks.) Then see if
1222 * any other waiters for the lock can be woken up now.
1224 CleanUpLock(waitLock, proclock,
1225 LockMethods[lockmethodid], hashcode,
1230 * LockRelease -- look up 'locktag' and release one 'lockmode' lock on it.
1231 * Release a session lock if 'sessionLock' is true, else release a
1232 * regular transaction lock.
1234 * Side Effects: find any waiting processes that are now wakable,
1235 * grant them their requested locks and awaken them.
1236 * (We have to grant the lock here to avoid a race between
1237 * the waking process and any new process to
1238 * come along and request the lock.)
1241 LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
1243 LOCKMETHODID lockmethodid = locktag->locktag_lockmethodid;
1244 LockMethod lockMethodTable;
1245 LOCALLOCKTAG localtag;
1246 LOCALLOCK *locallock;
1249 LWLockId partitionLock;
1252 if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
1253 elog(ERROR, "unrecognized lock method: %d", lockmethodid);
1254 lockMethodTable = LockMethods[lockmethodid];
1255 if (lockmode <= 0 || lockmode > lockMethodTable->numLockModes)
1256 elog(ERROR, "unrecognized lock mode: %d", lockmode);
1259 if (LOCK_DEBUG_ENABLED(locktag))
1260 elog(LOG, "LockRelease: lock [%u,%u] %s",
1261 locktag->locktag_field1, locktag->locktag_field2,
1262 lockMethodTable->lockModeNames[lockmode]);
1266 * Find the LOCALLOCK entry for this lock and lockmode
1268 MemSet(&localtag, 0, sizeof(localtag)); /* must clear padding */
1269 localtag.lock = *locktag;
1270 localtag.mode = lockmode;
1272 locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash,
1277 * let the caller print its own error message, too. Do not ereport(ERROR).
1279 if (!locallock || locallock->nLocks <= 0)
1281 elog(WARNING, "you don't own a lock of type %s",
1282 lockMethodTable->lockModeNames[lockmode]);
1287 * Decrease the count for the resource owner.
1290 LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
1291 ResourceOwner owner;
1294 /* Session locks are never transactional, else check table */
1295 if (!sessionLock && lockMethodTable->transactional)
1296 owner = CurrentResourceOwner;
1300 for (i = locallock->numLockOwners - 1; i >= 0; i--)
1302 if (lockOwners[i].owner == owner)
1304 Assert(lockOwners[i].nLocks > 0);
1305 if (--lockOwners[i].nLocks == 0)
1307 /* compact out unused slot */
1308 locallock->numLockOwners--;
1309 if (i < locallock->numLockOwners)
1310 lockOwners[i] = lockOwners[locallock->numLockOwners];
1317 /* don't release a lock belonging to another owner */
1318 elog(WARNING, "you don't own a lock of type %s",
1319 lockMethodTable->lockModeNames[lockmode]);
1325 * Decrease the total local count. If we're still holding the lock, we're
1328 locallock->nLocks--;
1330 if (locallock->nLocks > 0)
1334 * Otherwise we've got to mess with the shared lock table.
1336 partitionLock = LockHashPartitionLock(locallock->hashcode);
1338 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1341 * We don't need to re-find the lock or proclock, since we kept their
1342 * addresses in the locallock table, and they couldn't have been removed
1343 * while we were holding a lock on them.
1345 lock = locallock->lock;
1346 LOCK_PRINT("LockRelease: found", lock, lockmode);
1347 proclock = locallock->proclock;
1348 PROCLOCK_PRINT("LockRelease: found", proclock);
1351 * Double-check that we are actually holding a lock of the type we want to
1354 if (!(proclock->holdMask & LOCKBIT_ON(lockmode)))
1356 PROCLOCK_PRINT("LockRelease: WRONGTYPE", proclock);
1357 LWLockRelease(partitionLock);
1358 elog(WARNING, "you don't own a lock of type %s",
1359 lockMethodTable->lockModeNames[lockmode]);
1360 RemoveLocalLock(locallock);
1365 * Do the releasing. CleanUpLock will waken any now-wakable waiters.
1367 wakeupNeeded = UnGrantLock(lock, lockmode, proclock, lockMethodTable);
1369 CleanUpLock(lock, proclock,
1370 lockMethodTable, locallock->hashcode,
1373 LWLockRelease(partitionLock);
1375 RemoveLocalLock(locallock);
1380 * LockReleaseAll -- Release all locks of the specified lock method that
1381 * are held by the current process.
1383 * Well, not necessarily *all* locks. The available behaviors are:
1384 * allLocks == true: release all locks including session locks.
1385 * allLocks == false: release all non-session locks.
1388 LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
1390 HASH_SEQ_STATUS status;
1391 LockMethod lockMethodTable;
1394 LOCALLOCK *locallock;
1399 if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
1400 elog(ERROR, "unrecognized lock method: %d", lockmethodid);
1401 lockMethodTable = LockMethods[lockmethodid];
1404 if (*(lockMethodTable->trace_flag))
1405 elog(LOG, "LockReleaseAll: lockmethod=%d", lockmethodid);
1408 numLockModes = lockMethodTable->numLockModes;
1411 * First we run through the locallock table and get rid of unwanted
1412 * entries, then we scan the process's proclocks and get rid of those. We
1413 * do this separately because we may have multiple locallock entries
1414 * pointing to the same proclock, and we daren't end up with any dangling
1417 hash_seq_init(&status, LockMethodLocalHash);
1419 while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
1421 if (locallock->proclock == NULL || locallock->lock == NULL)
1424 * We must've run out of shared memory while trying to set up this
1425 * lock. Just forget the local entry.
1427 Assert(locallock->nLocks == 0);
1428 RemoveLocalLock(locallock);
1432 /* Ignore items that are not of the lockmethod to be removed */
1433 if (LOCALLOCK_LOCKMETHOD(*locallock) != lockmethodid)
1437 * If we are asked to release all locks, we can just zap the entry.
1438 * Otherwise, must scan to see if there are session locks. We assume
1439 * there is at most one lockOwners entry for session locks.
1443 LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
1445 /* If it's above array position 0, move it down to 0 */
1446 for (i = locallock->numLockOwners - 1; i > 0; i--)
1448 if (lockOwners[i].owner == NULL)
1450 lockOwners[0] = lockOwners[i];
1455 if (locallock->numLockOwners > 0 &&
1456 lockOwners[0].owner == NULL &&
1457 lockOwners[0].nLocks > 0)
1459 /* Fix the locallock to show just the session locks */
1460 locallock->nLocks = lockOwners[0].nLocks;
1461 locallock->numLockOwners = 1;
1462 /* We aren't deleting this locallock, so done */
1467 /* Mark the proclock to show we need to release this lockmode */
1468 if (locallock->nLocks > 0)
1469 locallock->proclock->releaseMask |= LOCKBIT_ON(locallock->tag.mode);
1471 /* And remove the locallock hashtable entry */
1472 RemoveLocalLock(locallock);
1476 * Now, scan each lock partition separately.
1478 for (partition = 0; partition < NUM_LOCK_PARTITIONS; partition++)
1480 LWLockId partitionLock = FirstLockMgrLock + partition;
1481 SHM_QUEUE *procLocks = &(MyProc->myProcLocks[partition]);
1483 proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
1484 offsetof(PROCLOCK, procLink));
1487 continue; /* needn't examine this partition */
1489 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1493 bool wakeupNeeded = false;
1494 PROCLOCK *nextplock;
1496 /* Get link first, since we may unlink/delete this proclock */
1497 nextplock = (PROCLOCK *)
1498 SHMQueueNext(procLocks, &proclock->procLink,
1499 offsetof(PROCLOCK, procLink));
1501 Assert(proclock->tag.myProc == MyProc);
1503 lock = proclock->tag.myLock;
1505 /* Ignore items that are not of the lockmethod to be removed */
1506 if (LOCK_LOCKMETHOD(*lock) != lockmethodid)
1510 * In allLocks mode, force release of all locks even if locallock
1511 * table had problems
1514 proclock->releaseMask = proclock->holdMask;
1516 Assert((proclock->releaseMask & ~proclock->holdMask) == 0);
1519 * Ignore items that have nothing to be released, unless they have
1520 * holdMask == 0 and are therefore recyclable
1522 if (proclock->releaseMask == 0 && proclock->holdMask != 0)
1525 PROCLOCK_PRINT("LockReleaseAll", proclock);
1526 LOCK_PRINT("LockReleaseAll", lock, 0);
1527 Assert(lock->nRequested >= 0);
1528 Assert(lock->nGranted >= 0);
1529 Assert(lock->nGranted <= lock->nRequested);
1530 Assert((proclock->holdMask & ~lock->grantMask) == 0);
1533 * Release the previously-marked lock modes
1535 for (i = 1; i <= numLockModes; i++)
1537 if (proclock->releaseMask & LOCKBIT_ON(i))
1538 wakeupNeeded |= UnGrantLock(lock, i, proclock,
1541 Assert((lock->nRequested >= 0) && (lock->nGranted >= 0));
1542 Assert(lock->nGranted <= lock->nRequested);
1543 LOCK_PRINT("LockReleaseAll: updated", lock, 0);
1545 proclock->releaseMask = 0;
1547 /* CleanUpLock will wake up waiters if needed. */
1548 CleanUpLock(lock, proclock,
1550 LockTagHashCode(&lock->tag),
1554 proclock = nextplock;
1555 } /* loop over PROCLOCKs within this partition */
1557 LWLockRelease(partitionLock);
1558 } /* loop over partitions */
1561 if (*(lockMethodTable->trace_flag))
1562 elog(LOG, "LockReleaseAll done");
1567 * LockReleaseCurrentOwner
1568 * Release all locks belonging to CurrentResourceOwner
1571 LockReleaseCurrentOwner(void)
1573 HASH_SEQ_STATUS status;
1574 LOCALLOCK *locallock;
1575 LOCALLOCKOWNER *lockOwners;
1578 hash_seq_init(&status, LockMethodLocalHash);
1580 while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
1582 /* Ignore items that must be nontransactional */
1583 if (!LockMethods[LOCALLOCK_LOCKMETHOD(*locallock)]->transactional)
1586 /* Scan to see if there are any locks belonging to current owner */
1587 lockOwners = locallock->lockOwners;
1588 for (i = locallock->numLockOwners - 1; i >= 0; i--)
1590 if (lockOwners[i].owner == CurrentResourceOwner)
1592 Assert(lockOwners[i].nLocks > 0);
1593 if (lockOwners[i].nLocks < locallock->nLocks)
1596 * We will still hold this lock after forgetting this
1599 locallock->nLocks -= lockOwners[i].nLocks;
1600 /* compact out unused slot */
1601 locallock->numLockOwners--;
1602 if (i < locallock->numLockOwners)
1603 lockOwners[i] = lockOwners[locallock->numLockOwners];
1607 Assert(lockOwners[i].nLocks == locallock->nLocks);
1608 /* We want to call LockRelease just once */
1609 lockOwners[i].nLocks = 1;
1610 locallock->nLocks = 1;
1611 if (!LockRelease(&locallock->tag.lock,
1612 locallock->tag.mode,
1614 elog(WARNING, "LockReleaseCurrentOwner: failed??");
1623 * LockReassignCurrentOwner
1624 * Reassign all locks belonging to CurrentResourceOwner to belong
1625 * to its parent resource owner
1628 LockReassignCurrentOwner(void)
1630 ResourceOwner parent = ResourceOwnerGetParent(CurrentResourceOwner);
1631 HASH_SEQ_STATUS status;
1632 LOCALLOCK *locallock;
1633 LOCALLOCKOWNER *lockOwners;
1635 Assert(parent != NULL);
1637 hash_seq_init(&status, LockMethodLocalHash);
1639 while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
1645 /* Ignore items that must be nontransactional */
1646 if (!LockMethods[LOCALLOCK_LOCKMETHOD(*locallock)]->transactional)
1650 * Scan to see if there are any locks belonging to current owner or
1653 lockOwners = locallock->lockOwners;
1654 for (i = locallock->numLockOwners - 1; i >= 0; i--)
1656 if (lockOwners[i].owner == CurrentResourceOwner)
1658 else if (lockOwners[i].owner == parent)
1663 continue; /* no current locks */
1667 /* Parent has no slot, so just give it child's slot */
1668 lockOwners[ic].owner = parent;
1672 /* Merge child's count with parent's */
1673 lockOwners[ip].nLocks += lockOwners[ic].nLocks;
1674 /* compact out unused slot */
1675 locallock->numLockOwners--;
1676 if (ic < locallock->numLockOwners)
1677 lockOwners[ic] = lockOwners[locallock->numLockOwners];
1685 * Do the preparatory work for a PREPARE: make 2PC state file records
1686 * for all locks currently held.
1688 * Non-transactional locks are ignored.
1690 * There are some special cases that we error out on: we can't be holding
1691 * any session locks (should be OK since only VACUUM uses those) and we
1692 * can't be holding any locks on temporary objects (since that would mess
1693 * up the current backend if it tries to exit before the prepared xact is
1697 AtPrepare_Locks(void)
1699 HASH_SEQ_STATUS status;
1700 LOCALLOCK *locallock;
1703 * We don't need to touch shared memory for this --- all the necessary
1704 * state information is in the locallock table.
1706 hash_seq_init(&status, LockMethodLocalHash);
1708 while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
1710 TwoPhaseLockRecord record;
1711 LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
1714 /* Ignore nontransactional locks */
1715 if (!LockMethods[LOCALLOCK_LOCKMETHOD(*locallock)]->transactional)
1718 /* Ignore it if we don't actually hold the lock */
1719 if (locallock->nLocks <= 0)
1722 /* Scan to verify there are no session locks */
1723 for (i = locallock->numLockOwners - 1; i >= 0; i--)
1725 /* elog not ereport since this should not happen */
1726 if (lockOwners[i].owner == NULL)
1727 elog(ERROR, "cannot PREPARE when session locks exist");
1730 /* Can't handle it if the lock is on a temporary object */
1731 if (locallock->isTempObject)
1733 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1734 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1737 * Create a 2PC record.
1739 memcpy(&(record.locktag), &(locallock->tag.lock), sizeof(LOCKTAG));
1740 record.lockmode = locallock->tag.mode;
1742 RegisterTwoPhaseRecord(TWOPHASE_RM_LOCK_ID, 0,
1743 &record, sizeof(TwoPhaseLockRecord));
1749 * Clean up after successful PREPARE
1751 * Here, we want to transfer ownership of our locks to a dummy PGPROC
1752 * that's now associated with the prepared transaction, and we want to
1753 * clean out the corresponding entries in the LOCALLOCK table.
1755 * Note: by removing the LOCALLOCK entries, we are leaving dangling
1756 * pointers in the transaction's resource owner. This is OK at the
1757 * moment since resowner.c doesn't try to free locks retail at a toplevel
1758 * transaction commit or abort. We could alternatively zero out nLocks
1759 * and leave the LOCALLOCK entries to be garbage-collected by LockReleaseAll,
1760 * but that probably costs more cycles.
1763 PostPrepare_Locks(TransactionId xid)
1765 PGPROC *newproc = TwoPhaseGetDummyProc(xid);
1766 HASH_SEQ_STATUS status;
1767 LOCALLOCK *locallock;
1770 PROCLOCKTAG proclocktag;
1774 /* This is a critical section: any error means big trouble */
1775 START_CRIT_SECTION();
1778 * First we run through the locallock table and get rid of unwanted
1779 * entries, then we scan the process's proclocks and transfer them to the
1782 * We do this separately because we may have multiple locallock entries
1783 * pointing to the same proclock, and we daren't end up with any dangling
1786 hash_seq_init(&status, LockMethodLocalHash);
1788 while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
1790 if (locallock->proclock == NULL || locallock->lock == NULL)
1793 * We must've run out of shared memory while trying to set up this
1794 * lock. Just forget the local entry.
1796 Assert(locallock->nLocks == 0);
1797 RemoveLocalLock(locallock);
1801 /* Ignore nontransactional locks */
1802 if (!LockMethods[LOCALLOCK_LOCKMETHOD(*locallock)]->transactional)
1805 /* We already checked there are no session locks */
1807 /* Mark the proclock to show we need to release this lockmode */
1808 if (locallock->nLocks > 0)
1809 locallock->proclock->releaseMask |= LOCKBIT_ON(locallock->tag.mode);
1811 /* And remove the locallock hashtable entry */
1812 RemoveLocalLock(locallock);
1816 * Now, scan each lock partition separately.
1818 for (partition = 0; partition < NUM_LOCK_PARTITIONS; partition++)
1820 LWLockId partitionLock = FirstLockMgrLock + partition;
1821 SHM_QUEUE *procLocks = &(MyProc->myProcLocks[partition]);
1823 proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
1824 offsetof(PROCLOCK, procLink));
1827 continue; /* needn't examine this partition */
1829 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1833 PROCLOCK *nextplock;
1835 PROCLOCK *newproclock;
1837 /* Get link first, since we may unlink/delete this proclock */
1838 nextplock = (PROCLOCK *)
1839 SHMQueueNext(procLocks, &proclock->procLink,
1840 offsetof(PROCLOCK, procLink));
1842 Assert(proclock->tag.myProc == MyProc);
1844 lock = proclock->tag.myLock;
1846 /* Ignore nontransactional locks */
1847 if (!LockMethods[LOCK_LOCKMETHOD(*lock)]->transactional)
1850 PROCLOCK_PRINT("PostPrepare_Locks", proclock);
1851 LOCK_PRINT("PostPrepare_Locks", lock, 0);
1852 Assert(lock->nRequested >= 0);
1853 Assert(lock->nGranted >= 0);
1854 Assert(lock->nGranted <= lock->nRequested);
1855 Assert((proclock->holdMask & ~lock->grantMask) == 0);
1858 * Since there were no session locks, we should be releasing all
1861 if (proclock->releaseMask != proclock->holdMask)
1862 elog(PANIC, "we seem to have dropped a bit somewhere");
1864 holdMask = proclock->holdMask;
1867 * We cannot simply modify proclock->tag.myProc to reassign
1868 * ownership of the lock, because that's part of the hash key and
1869 * the proclock would then be in the wrong hash chain. So, unlink
1870 * and delete the old proclock; create a new one with the right
1871 * contents; and link it into place. We do it in this order to be
1872 * certain we won't run out of shared memory (the way dynahash.c
1873 * works, the deleted object is certain to be available for
1876 SHMQueueDelete(&proclock->lockLink);
1877 SHMQueueDelete(&proclock->procLink);
1878 if (!hash_search(LockMethodProcLockHash,
1879 (void *) &(proclock->tag),
1881 elog(PANIC, "proclock table corrupted");
1884 * Create the hash key for the new proclock table.
1886 proclocktag.myLock = lock;
1887 proclocktag.myProc = newproc;
1889 newproclock = (PROCLOCK *) hash_search(LockMethodProcLockHash,
1890 (void *) &proclocktag,
1891 HASH_ENTER_NULL, &found);
1893 ereport(PANIC, /* should not happen */
1894 (errcode(ERRCODE_OUT_OF_MEMORY),
1895 errmsg("out of shared memory"),
1896 errdetail("Not enough memory for reassigning the prepared transaction's locks.")));
1899 * If new, initialize the new entry
1903 newproclock->holdMask = 0;
1904 newproclock->releaseMask = 0;
1905 /* Add new proclock to appropriate lists */
1906 SHMQueueInsertBefore(&lock->procLocks, &newproclock->lockLink);
1907 SHMQueueInsertBefore(&(newproc->myProcLocks[partition]),
1908 &newproclock->procLink);
1909 PROCLOCK_PRINT("PostPrepare_Locks: new", newproclock);
1913 PROCLOCK_PRINT("PostPrepare_Locks: found", newproclock);
1914 Assert((newproclock->holdMask & ~lock->grantMask) == 0);
1918 * Pass over the identified lock ownership.
1920 Assert((newproclock->holdMask & holdMask) == 0);
1921 newproclock->holdMask |= holdMask;
1924 proclock = nextplock;
1925 } /* loop over PROCLOCKs within this partition */
1927 LWLockRelease(partitionLock);
1928 } /* loop over partitions */
1935 * Estimate shared-memory space used for lock tables
1941 long max_table_size;
1943 /* lock hash table */
1944 max_table_size = NLOCKENTS();
1945 size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK)));
1947 /* proclock hash table */
1948 max_table_size *= 2;
1949 size = add_size(size, hash_estimate_size(max_table_size, sizeof(PROCLOCK)));
1952 * Since NLOCKENTS is only an estimate, add 10% safety margin.
1954 size = add_size(size, size / 10);
1960 * GetLockStatusData - Return a summary of the lock manager's internal
1961 * status, for use in a user-level reporting function.
1963 * The return data consists of an array of PROCLOCK objects, with the
1964 * associated PGPROC and LOCK objects for each. Note that multiple
1965 * copies of the same PGPROC and/or LOCK objects are likely to appear.
1966 * It is the caller's responsibility to match up duplicates if wanted.
1968 * The design goal is to hold the LWLocks for as short a time as possible;
1969 * thus, this function simply makes a copy of the necessary data and releases
1970 * the locks, allowing the caller to contemplate and format the data for as
1971 * long as it pleases.
1974 GetLockStatusData(void)
1978 HASH_SEQ_STATUS seqstat;
1983 data = (LockData *) palloc(sizeof(LockData));
1986 * Acquire lock on the entire shared lock data structure. We can't
1987 * operate one partition at a time if we want to deliver a self-consistent
1988 * view of the state.
1990 * Since this is a read-only operation, we take shared instead of exclusive
1991 * lock. There's not a whole lot of point to this, because all the normal
1992 * operations require exclusive lock, but it doesn't hurt anything either.
1993 * It will at least allow two backends to do GetLockStatusData in parallel.
1995 * Must grab LWLocks in partition-number order to avoid LWLock deadlock.
1997 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1998 LWLockAcquire(FirstLockMgrLock + i, LW_SHARED);
2000 /* Now we can safely count the number of proclocks */
2001 els = hash_get_num_entries(LockMethodProcLockHash);
2003 data->nelements = els;
2004 data->proclocks = (PROCLOCK *) palloc(sizeof(PROCLOCK) * els);
2005 data->procs = (PGPROC *) palloc(sizeof(PGPROC) * els);
2006 data->locks = (LOCK *) palloc(sizeof(LOCK) * els);
2008 /* Now scan the tables to copy the data */
2009 hash_seq_init(&seqstat, LockMethodProcLockHash);
2012 while ((proclock = (PROCLOCK *) hash_seq_search(&seqstat)))
2014 PGPROC *proc = proclock->tag.myProc;
2015 LOCK *lock = proclock->tag.myLock;
2017 memcpy(&(data->proclocks[el]), proclock, sizeof(PROCLOCK));
2018 memcpy(&(data->procs[el]), proc, sizeof(PGPROC));
2019 memcpy(&(data->locks[el]), lock, sizeof(LOCK));
2024 /* And release locks */
2025 for (i = NUM_LOCK_PARTITIONS; --i >= 0; )
2026 LWLockRelease(FirstLockMgrLock + i);
2028 Assert(el == data->nelements);
2033 /* Provide the textual name of any lock mode */
2035 GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
2037 Assert(lockmethodid > 0 && lockmethodid < lengthof(LockMethods));
2038 Assert(mode > 0 && mode <= LockMethods[lockmethodid]->numLockModes);
2039 return LockMethods[lockmethodid]->lockModeNames[mode];
2044 * Dump all locks in the given proc's myProcLocks lists.
2046 * Caller is responsible for having acquired appropriate LWLocks.
2049 DumpLocks(PGPROC *proc)
2051 SHM_QUEUE *procLocks;
2060 LOCK_PRINT("DumpLocks: waiting on", proc->waitLock, 0);
2062 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
2064 procLocks = &(proc->myProcLocks[i]);
2066 proclock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
2067 offsetof(PROCLOCK, procLink));
2071 Assert(proclock->tag.myProc == proc);
2073 lock = proclock->tag.myLock;
2075 PROCLOCK_PRINT("DumpLocks", proclock);
2076 LOCK_PRINT("DumpLocks", lock, 0);
2078 proclock = (PROCLOCK *)
2079 SHMQueueNext(procLocks, &proclock->procLink,
2080 offsetof(PROCLOCK, procLink));
2086 * Dump all lmgr locks.
2088 * Caller is responsible for having acquired appropriate LWLocks.
2096 HASH_SEQ_STATUS status;
2100 if (proc && proc->waitLock)
2101 LOCK_PRINT("DumpAllLocks: waiting on", proc->waitLock, 0);
2103 hash_seq_init(&status, LockMethodProcLockHash);
2105 while ((proclock = (PROCLOCK *) hash_seq_search(&status)) != NULL)
2107 PROCLOCK_PRINT("DumpAllLocks", proclock);
2109 lock = proclock->tag.myLock;
2111 LOCK_PRINT("DumpAllLocks", lock, 0);
2113 elog(LOG, "DumpAllLocks: proclock->tag.myLock = NULL");
2116 #endif /* LOCK_DEBUG */
2119 * LOCK 2PC resource manager's routines
2123 * Re-acquire a lock belonging to a transaction that was prepared.
2125 * Because this function is run at db startup, re-acquiring the locks should
2126 * never conflict with running transactions because there are none. We
2127 * assume that the lock state represented by the stored 2PC files is legal.
2130 lock_twophase_recover(TransactionId xid, uint16 info,
2131 void *recdata, uint32 len)
2133 TwoPhaseLockRecord *rec = (TwoPhaseLockRecord *) recdata;
2134 PGPROC *proc = TwoPhaseGetDummyProc(xid);
2137 LOCKMETHODID lockmethodid;
2140 PROCLOCKTAG proclocktag;
2143 uint32 proclock_hashcode;
2145 LWLockId partitionLock;
2146 LockMethod lockMethodTable;
2148 Assert(len == sizeof(TwoPhaseLockRecord));
2149 locktag = &rec->locktag;
2150 lockmode = rec->lockmode;
2151 lockmethodid = locktag->locktag_lockmethodid;
2153 if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
2154 elog(ERROR, "unrecognized lock method: %d", lockmethodid);
2155 lockMethodTable = LockMethods[lockmethodid];
2157 hashcode = LockTagHashCode(locktag);
2158 partition = LockHashPartition(hashcode);
2159 partitionLock = LockHashPartitionLock(hashcode);
2161 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
2164 * Find or create a lock with this tag.
2166 lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
2173 LWLockRelease(partitionLock);
2175 (errcode(ERRCODE_OUT_OF_MEMORY),
2176 errmsg("out of shared memory"),
2177 errhint("You may need to increase max_locks_per_transaction.")));
2181 * if it's a new lock object, initialize it
2185 lock->grantMask = 0;
2187 SHMQueueInit(&(lock->procLocks));
2188 ProcQueueInit(&(lock->waitProcs));
2189 lock->nRequested = 0;
2191 MemSet(lock->requested, 0, sizeof(int) * MAX_LOCKMODES);
2192 MemSet(lock->granted, 0, sizeof(int) * MAX_LOCKMODES);
2193 LOCK_PRINT("lock_twophase_recover: new", lock, lockmode);
2197 LOCK_PRINT("lock_twophase_recover: found", lock, lockmode);
2198 Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
2199 Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
2200 Assert(lock->nGranted <= lock->nRequested);
2204 * Create the hash key for the proclock table.
2206 proclocktag.myLock = lock;
2207 proclocktag.myProc = proc;
2209 proclock_hashcode = ProcLockHashCode(&proclocktag, hashcode);
2212 * Find or create a proclock entry with this tag
2214 proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
2215 (void *) &proclocktag,
2221 /* Ooops, not enough shmem for the proclock */
2222 if (lock->nRequested == 0)
2225 * There are no other requestors of this lock, so garbage-collect
2226 * the lock object. We *must* do this to avoid a permanent leak
2227 * of shared memory, because there won't be anything to cause
2228 * anyone to release the lock object later.
2230 Assert(SHMQueueEmpty(&(lock->procLocks)));
2231 if (!hash_search_with_hash_value(LockMethodLockHash,
2232 (void *) &(lock->tag),
2236 elog(PANIC, "lock table corrupted");
2238 LWLockRelease(partitionLock);
2240 (errcode(ERRCODE_OUT_OF_MEMORY),
2241 errmsg("out of shared memory"),
2242 errhint("You may need to increase max_locks_per_transaction.")));
2246 * If new, initialize the new entry
2250 proclock->holdMask = 0;
2251 proclock->releaseMask = 0;
2252 /* Add proclock to appropriate lists */
2253 SHMQueueInsertBefore(&lock->procLocks, &proclock->lockLink);
2254 SHMQueueInsertBefore(&(proc->myProcLocks[partition]),
2255 &proclock->procLink);
2256 PROCLOCK_PRINT("lock_twophase_recover: new", proclock);
2260 PROCLOCK_PRINT("lock_twophase_recover: found", proclock);
2261 Assert((proclock->holdMask & ~lock->grantMask) == 0);
2265 * lock->nRequested and lock->requested[] count the total number of
2266 * requests, whether granted or waiting, so increment those immediately.
2269 lock->requested[lockmode]++;
2270 Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
2273 * We shouldn't already hold the desired lock.
2275 if (proclock->holdMask & LOCKBIT_ON(lockmode))
2276 elog(ERROR, "lock %s on object %u/%u/%u is already held",
2277 lockMethodTable->lockModeNames[lockmode],
2278 lock->tag.locktag_field1, lock->tag.locktag_field2,
2279 lock->tag.locktag_field3);
2282 * We ignore any possible conflicts and just grant ourselves the lock.
2284 GrantLock(lock, proclock, lockmode);
2286 LWLockRelease(partitionLock);
2290 * 2PC processing routine for COMMIT PREPARED case.
2292 * Find and release the lock indicated by the 2PC record.
2295 lock_twophase_postcommit(TransactionId xid, uint16 info,
2296 void *recdata, uint32 len)
2298 TwoPhaseLockRecord *rec = (TwoPhaseLockRecord *) recdata;
2299 PGPROC *proc = TwoPhaseGetDummyProc(xid);
2302 LOCKMETHODID lockmethodid;
2305 PROCLOCKTAG proclocktag;
2307 uint32 proclock_hashcode;
2308 LWLockId partitionLock;
2309 LockMethod lockMethodTable;
2312 Assert(len == sizeof(TwoPhaseLockRecord));
2313 locktag = &rec->locktag;
2314 lockmode = rec->lockmode;
2315 lockmethodid = locktag->locktag_lockmethodid;
2317 if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
2318 elog(ERROR, "unrecognized lock method: %d", lockmethodid);
2319 lockMethodTable = LockMethods[lockmethodid];
2321 hashcode = LockTagHashCode(locktag);
2322 partitionLock = LockHashPartitionLock(hashcode);
2324 LWLockAcquire(partitionLock, LW_EXCLUSIVE);
2327 * Re-find the lock object (it had better be there).
2329 lock = (LOCK *) hash_search_with_hash_value(LockMethodLockHash,
2335 elog(PANIC, "failed to re-find shared lock object");
2338 * Re-find the proclock object (ditto).
2340 proclocktag.myLock = lock;
2341 proclocktag.myProc = proc;
2343 proclock_hashcode = ProcLockHashCode(&proclocktag, hashcode);
2345 proclock = (PROCLOCK *) hash_search_with_hash_value(LockMethodProcLockHash,
2346 (void *) &proclocktag,
2351 elog(PANIC, "failed to re-find shared proclock object");
2354 * Double-check that we are actually holding a lock of the type we want to
2357 if (!(proclock->holdMask & LOCKBIT_ON(lockmode)))
2359 PROCLOCK_PRINT("lock_twophase_postcommit: WRONGTYPE", proclock);
2360 LWLockRelease(partitionLock);
2361 elog(WARNING, "you don't own a lock of type %s",
2362 lockMethodTable->lockModeNames[lockmode]);
2367 * Do the releasing. CleanUpLock will waken any now-wakable waiters.
2369 wakeupNeeded = UnGrantLock(lock, lockmode, proclock, lockMethodTable);
2371 CleanUpLock(lock, proclock,
2372 lockMethodTable, hashcode,
2375 LWLockRelease(partitionLock);
2379 * 2PC processing routine for ROLLBACK PREPARED case.
2381 * This is actually just the same as the COMMIT case.
2384 lock_twophase_postabort(TransactionId xid, uint16 info,
2385 void *recdata, uint32 len)
2387 lock_twophase_postcommit(xid, info, recdata, len);