PostgreSQL Source Code  git master
lmgr.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * lmgr.c
4  * POSTGRES lock manager code
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/storage/lmgr/lmgr.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "access/subtrans.h"
19 #include "access/xact.h"
20 #include "catalog/catalog.h"
21 #include "commands/progress.h"
22 #include "miscadmin.h"
23 #include "pgstat.h"
24 #include "storage/lmgr.h"
25 #include "storage/proc.h"
26 #include "storage/procarray.h"
27 #include "storage/sinvaladt.h"
28 #include "utils/inval.h"
29 
30 
31 /*
32  * Per-backend counter for generating speculative insertion tokens.
33  *
34  * This may wrap around, but that's OK as it's only used for the short
35  * duration between inserting a tuple and checking that there are no (unique)
36  * constraint violations. It's theoretically possible that a backend sees a
37  * tuple that was speculatively inserted by another backend, but before it has
38  * started waiting on the token, the other backend completes its insertion,
39  * and then performs 2^32 unrelated insertions. And after all that, the
40  * first backend finally calls SpeculativeInsertionLockAcquire(), with the
41  * intention of waiting for the first insertion to complete, but ends up
42  * waiting for the latest unrelated insertion instead. Even then, nothing
43  * particularly bad happens: in the worst case they deadlock, causing one of
44  * the transactions to abort.
45  */
47 
48 
49 /*
50  * Struct to hold context info for transaction lock waits.
51  *
52  * 'oper' is the operation that needs to wait for the other transaction; 'rel'
53  * and 'ctid' specify the address of the tuple being waited for.
54  */
55 typedef struct XactLockTableWaitInfo
56 {
61 
62 static void XactLockTableWaitErrorCb(void *arg);
63 
64 /*
65  * RelationInitLockInfo
66  * Initializes the lock information in a relation descriptor.
67  *
68  * relcache.c must call this during creation of any reldesc.
69  */
70 void
72 {
73  Assert(RelationIsValid(relation));
75 
76  relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);
77 
78  if (relation->rd_rel->relisshared)
80  else
82 }
83 
84 /*
85  * SetLocktagRelationOid
86  * Set up a locktag for a relation, given only relation OID
87  */
88 static inline void
90 {
91  Oid dbid;
92 
93  if (IsSharedRelation(relid))
94  dbid = InvalidOid;
95  else
96  dbid = MyDatabaseId;
97 
98  SET_LOCKTAG_RELATION(*tag, dbid, relid);
99 }
100 
101 /*
102  * LockRelationOid
103  *
104  * Lock a relation given only its OID. This should generally be used
105  * before attempting to open the relation's relcache entry.
106  */
107 void
108 LockRelationOid(Oid relid, LOCKMODE lockmode)
109 {
110  LOCKTAG tag;
111  LOCALLOCK *locallock;
113 
114  SetLocktagRelationOid(&tag, relid);
115 
116  res = LockAcquireExtended(&tag, lockmode, false, false, true, &locallock);
117 
118  /*
119  * Now that we have the lock, check for invalidation messages, so that we
120  * will update or flush any stale relcache entry before we try to use it.
121  * RangeVarGetRelid() specifically relies on us for this. We can skip
122  * this in the not-uncommon case that we already had the same type of lock
123  * being requested, since then no one else could have modified the
124  * relcache entry in an undesirable way. (In the case where our own xact
125  * modifies the rel, the relcache update happens via
126  * CommandCounterIncrement, not here.)
127  *
128  * However, in corner cases where code acts on tables (usually catalogs)
129  * recursively, we might get here while still processing invalidation
130  * messages in some outer execution of this function or a sibling. The
131  * "cleared" status of the lock tells us whether we really are done
132  * absorbing relevant inval messages.
133  */
135  {
137  MarkLockClear(locallock);
138  }
139 }
140 
141 /*
142  * ConditionalLockRelationOid
143  *
144  * As above, but only lock if we can get the lock without blocking.
145  * Returns true iff the lock was acquired.
146  *
147  * NOTE: we do not currently need conditional versions of all the
148  * LockXXX routines in this file, but they could easily be added if needed.
149  */
150 bool
152 {
153  LOCKTAG tag;
154  LOCALLOCK *locallock;
156 
157  SetLocktagRelationOid(&tag, relid);
158 
159  res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock);
160 
161  if (res == LOCKACQUIRE_NOT_AVAIL)
162  return false;
163 
164  /*
165  * Now that we have the lock, check for invalidation messages; see notes
166  * in LockRelationOid.
167  */
169  {
171  MarkLockClear(locallock);
172  }
173 
174  return true;
175 }
176 
177 /*
178  * LockRelationId
179  *
180  * Lock, given a LockRelId. Same as LockRelationOid but take LockRelId as an
181  * input.
182  */
183 void
185 {
186  LOCKTAG tag;
187  LOCALLOCK *locallock;
189 
190  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
191 
192  res = LockAcquireExtended(&tag, lockmode, false, false, true, &locallock);
193 
194  /*
195  * Now that we have the lock, check for invalidation messages; see notes
196  * in LockRelationOid.
197  */
199  {
201  MarkLockClear(locallock);
202  }
203 }
204 
205 /*
206  * UnlockRelationId
207  *
208  * Unlock, given a LockRelId. This is preferred over UnlockRelationOid
209  * for speed reasons.
210  */
211 void
213 {
214  LOCKTAG tag;
215 
216  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
217 
218  LockRelease(&tag, lockmode, false);
219 }
220 
221 /*
222  * UnlockRelationOid
223  *
224  * Unlock, given only a relation Oid. Use UnlockRelationId if you can.
225  */
226 void
228 {
229  LOCKTAG tag;
230 
231  SetLocktagRelationOid(&tag, relid);
232 
233  LockRelease(&tag, lockmode, false);
234 }
235 
236 /*
237  * LockRelation
238  *
239  * This is a convenience routine for acquiring an additional lock on an
240  * already-open relation. Never try to do "relation_open(foo, NoLock)"
241  * and then lock with this.
242  */
243 void
244 LockRelation(Relation relation, LOCKMODE lockmode)
245 {
246  LOCKTAG tag;
247  LOCALLOCK *locallock;
249 
251  relation->rd_lockInfo.lockRelId.dbId,
252  relation->rd_lockInfo.lockRelId.relId);
253 
254  res = LockAcquireExtended(&tag, lockmode, false, false, true, &locallock);
255 
256  /*
257  * Now that we have the lock, check for invalidation messages; see notes
258  * in LockRelationOid.
259  */
261  {
263  MarkLockClear(locallock);
264  }
265 }
266 
267 /*
268  * ConditionalLockRelation
269  *
270  * This is a convenience routine for acquiring an additional lock on an
271  * already-open relation. Never try to do "relation_open(foo, NoLock)"
272  * and then lock with this.
273  */
274 bool
276 {
277  LOCKTAG tag;
278  LOCALLOCK *locallock;
280 
282  relation->rd_lockInfo.lockRelId.dbId,
283  relation->rd_lockInfo.lockRelId.relId);
284 
285  res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock);
286 
287  if (res == LOCKACQUIRE_NOT_AVAIL)
288  return false;
289 
290  /*
291  * Now that we have the lock, check for invalidation messages; see notes
292  * in LockRelationOid.
293  */
295  {
297  MarkLockClear(locallock);
298  }
299 
300  return true;
301 }
302 
303 /*
304  * UnlockRelation
305  *
306  * This is a convenience routine for unlocking a relation without also
307  * closing it.
308  */
309 void
310 UnlockRelation(Relation relation, LOCKMODE lockmode)
311 {
312  LOCKTAG tag;
313 
315  relation->rd_lockInfo.lockRelId.dbId,
316  relation->rd_lockInfo.lockRelId.relId);
317 
318  LockRelease(&tag, lockmode, false);
319 }
320 
321 /*
322  * CheckRelationLockedByMe
323  *
324  * Returns true if current transaction holds a lock on 'relation' of mode
325  * 'lockmode'. If 'orstronger' is true, a stronger lockmode is also OK.
326  * ("Stronger" is defined as "numerically higher", which is a bit
327  * semantically dubious but is OK for the purposes we use this for.)
328  */
329 bool
330 CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
331 {
332  LOCKTAG tag;
333 
335  relation->rd_lockInfo.lockRelId.dbId,
336  relation->rd_lockInfo.lockRelId.relId);
337 
338  return LockHeldByMe(&tag, lockmode, orstronger);
339 }
340 
341 /*
342  * CheckRelationOidLockedByMe
343  *
344  * Like the above, but takes an OID as argument.
345  */
346 bool
347 CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)
348 {
349  LOCKTAG tag;
350 
351  SetLocktagRelationOid(&tag, relid);
352 
353  return LockHeldByMe(&tag, lockmode, orstronger);
354 }
355 
356 /*
357  * LockHasWaitersRelation
358  *
359  * This is a function to check whether someone else is waiting for a
360  * lock which we are currently holding.
361  */
362 bool
364 {
365  LOCKTAG tag;
366 
368  relation->rd_lockInfo.lockRelId.dbId,
369  relation->rd_lockInfo.lockRelId.relId);
370 
371  return LockHasWaiters(&tag, lockmode, false);
372 }
373 
374 /*
375  * LockRelationIdForSession
376  *
377  * This routine grabs a session-level lock on the target relation. The
378  * session lock persists across transaction boundaries. It will be removed
379  * when UnlockRelationIdForSession() is called, or if an ereport(ERROR) occurs,
380  * or if the backend exits.
381  *
382  * Note that one should also grab a transaction-level lock on the rel
383  * in any transaction that actually uses the rel, to ensure that the
384  * relcache entry is up to date.
385  */
386 void
388 {
389  LOCKTAG tag;
390 
391  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
392 
393  (void) LockAcquire(&tag, lockmode, true, false);
394 }
395 
396 /*
397  * UnlockRelationIdForSession
398  */
399 void
401 {
402  LOCKTAG tag;
403 
404  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
405 
406  LockRelease(&tag, lockmode, true);
407 }
408 
409 /*
410  * LockRelationForExtension
411  *
412  * This lock tag is used to interlock addition of pages to relations.
413  * We need such locking because bufmgr/smgr definition of P_NEW is not
414  * race-condition-proof.
415  *
416  * We assume the caller is already holding some type of regular lock on
417  * the relation, so no AcceptInvalidationMessages call is needed here.
418  */
419 void
421 {
422  LOCKTAG tag;
423 
425  relation->rd_lockInfo.lockRelId.dbId,
426  relation->rd_lockInfo.lockRelId.relId);
427 
428  (void) LockAcquire(&tag, lockmode, false, false);
429 }
430 
431 /*
432  * ConditionalLockRelationForExtension
433  *
434  * As above, but only lock if we can get the lock without blocking.
435  * Returns true iff the lock was acquired.
436  */
437 bool
439 {
440  LOCKTAG tag;
441 
443  relation->rd_lockInfo.lockRelId.dbId,
444  relation->rd_lockInfo.lockRelId.relId);
445 
446  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
447 }
448 
449 /*
450  * RelationExtensionLockWaiterCount
451  *
452  * Count the number of processes waiting for the given relation extension lock.
453  */
454 int
456 {
457  LOCKTAG tag;
458 
460  relation->rd_lockInfo.lockRelId.dbId,
461  relation->rd_lockInfo.lockRelId.relId);
462 
463  return LockWaiterCount(&tag);
464 }
465 
466 /*
467  * UnlockRelationForExtension
468  */
469 void
471 {
472  LOCKTAG tag;
473 
475  relation->rd_lockInfo.lockRelId.dbId,
476  relation->rd_lockInfo.lockRelId.relId);
477 
478  LockRelease(&tag, lockmode, false);
479 }
480 
481 /*
482  * LockDatabaseFrozenIds
483  *
484  * This allows one backend per database to execute vac_update_datfrozenxid().
485  */
486 void
488 {
489  LOCKTAG tag;
490 
492 
493  (void) LockAcquire(&tag, lockmode, false, false);
494 }
495 
496 /*
497  * LockPage
498  *
499  * Obtain a page-level lock. This is currently used by some index access
500  * methods to lock individual index pages.
501  */
502 void
503 LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
504 {
505  LOCKTAG tag;
506 
507  SET_LOCKTAG_PAGE(tag,
508  relation->rd_lockInfo.lockRelId.dbId,
509  relation->rd_lockInfo.lockRelId.relId,
510  blkno);
511 
512  (void) LockAcquire(&tag, lockmode, false, false);
513 }
514 
515 /*
516  * ConditionalLockPage
517  *
518  * As above, but only lock if we can get the lock without blocking.
519  * Returns true iff the lock was acquired.
520  */
521 bool
523 {
524  LOCKTAG tag;
525 
526  SET_LOCKTAG_PAGE(tag,
527  relation->rd_lockInfo.lockRelId.dbId,
528  relation->rd_lockInfo.lockRelId.relId,
529  blkno);
530 
531  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
532 }
533 
534 /*
535  * UnlockPage
536  */
537 void
538 UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
539 {
540  LOCKTAG tag;
541 
542  SET_LOCKTAG_PAGE(tag,
543  relation->rd_lockInfo.lockRelId.dbId,
544  relation->rd_lockInfo.lockRelId.relId,
545  blkno);
546 
547  LockRelease(&tag, lockmode, false);
548 }
549 
550 /*
551  * LockTuple
552  *
553  * Obtain a tuple-level lock. This is used in a less-than-intuitive fashion
554  * because we can't afford to keep a separate lock in shared memory for every
555  * tuple. See heap_lock_tuple before using this!
556  */
557 void
558 LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
559 {
560  LOCKTAG tag;
561 
562  SET_LOCKTAG_TUPLE(tag,
563  relation->rd_lockInfo.lockRelId.dbId,
564  relation->rd_lockInfo.lockRelId.relId,
567 
568  (void) LockAcquire(&tag, lockmode, false, false);
569 }
570 
571 /*
572  * ConditionalLockTuple
573  *
574  * As above, but only lock if we can get the lock without blocking.
575  * Returns true iff the lock was acquired.
576  */
577 bool
579 {
580  LOCKTAG tag;
581 
582  SET_LOCKTAG_TUPLE(tag,
583  relation->rd_lockInfo.lockRelId.dbId,
584  relation->rd_lockInfo.lockRelId.relId,
587 
588  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
589 }
590 
591 /*
592  * UnlockTuple
593  */
594 void
595 UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
596 {
597  LOCKTAG tag;
598 
599  SET_LOCKTAG_TUPLE(tag,
600  relation->rd_lockInfo.lockRelId.dbId,
601  relation->rd_lockInfo.lockRelId.relId,
604 
605  LockRelease(&tag, lockmode, false);
606 }
607 
608 /*
609  * XactLockTableInsert
610  *
611  * Insert a lock showing that the given transaction ID is running ---
612  * this is done when an XID is acquired by a transaction or subtransaction.
613  * The lock can then be used to wait for the transaction to finish.
614  */
615 void
617 {
618  LOCKTAG tag;
619 
620  SET_LOCKTAG_TRANSACTION(tag, xid);
621 
622  (void) LockAcquire(&tag, ExclusiveLock, false, false);
623 }
624 
625 /*
626  * XactLockTableDelete
627  *
628  * Delete the lock showing that the given transaction ID is running.
629  * (This is never used for main transaction IDs; those locks are only
630  * released implicitly at transaction end. But we do use it for subtrans IDs.)
631  */
632 void
634 {
635  LOCKTAG tag;
636 
637  SET_LOCKTAG_TRANSACTION(tag, xid);
638 
639  LockRelease(&tag, ExclusiveLock, false);
640 }
641 
642 /*
643  * XactLockTableWait
644  *
645  * Wait for the specified transaction to commit or abort. If an operation
646  * is specified, an error context callback is set up. If 'oper' is passed as
647  * None, no error context callback is set up.
648  *
649  * Note that this does the right thing for subtransactions: if we wait on a
650  * subtransaction, we will exit as soon as it aborts or its top parent commits.
651  * It takes some extra work to ensure this, because to save on shared memory
652  * the XID lock of a subtransaction is released when it ends, whether
653  * successfully or unsuccessfully. So we have to check if it's "still running"
654  * and if so wait for its parent.
655  */
656 void
658  XLTW_Oper oper)
659 {
660  LOCKTAG tag;
663  bool first = true;
664 
665  /*
666  * If an operation is specified, set up our verbose error context
667  * callback.
668  */
669  if (oper != XLTW_None)
670  {
671  Assert(RelationIsValid(rel));
672  Assert(ItemPointerIsValid(ctid));
673 
674  info.rel = rel;
675  info.ctid = ctid;
676  info.oper = oper;
677 
679  callback.arg = &info;
680  callback.previous = error_context_stack;
682  }
683 
684  for (;;)
685  {
688 
689  SET_LOCKTAG_TRANSACTION(tag, xid);
690 
691  (void) LockAcquire(&tag, ShareLock, false, false);
692 
693  LockRelease(&tag, ShareLock, false);
694 
695  if (!TransactionIdIsInProgress(xid))
696  break;
697 
698  /*
699  * If the Xid belonged to a subtransaction, then the lock would have
700  * gone away as soon as it was finished; for correct tuple visibility,
701  * the right action is to wait on its parent transaction to go away.
702  * But instead of going levels up one by one, we can just wait for the
703  * topmost transaction to finish with the same end result, which also
704  * incurs less locktable traffic.
705  *
706  * Some uses of this function don't involve tuple visibility -- such
707  * as when building snapshots for logical decoding. It is possible to
708  * see a transaction in ProcArray before it registers itself in the
709  * locktable. The topmost transaction in that case is the same xid,
710  * so we try again after a short sleep. (Don't sleep the first time
711  * through, to avoid slowing down the normal case.)
712  */
713  if (!first)
714  pg_usleep(1000L);
715  first = false;
717  }
718 
719  if (oper != XLTW_None)
720  error_context_stack = callback.previous;
721 }
722 
723 /*
724  * ConditionalXactLockTableWait
725  *
726  * As above, but only lock if we can get the lock without blocking.
727  * Returns true if the lock was acquired.
728  */
729 bool
731 {
732  LOCKTAG tag;
733  bool first = true;
734 
735  for (;;)
736  {
739 
740  SET_LOCKTAG_TRANSACTION(tag, xid);
741 
742  if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
743  return false;
744 
745  LockRelease(&tag, ShareLock, false);
746 
747  if (!TransactionIdIsInProgress(xid))
748  break;
749 
750  /* See XactLockTableWait about this case */
751  if (!first)
752  pg_usleep(1000L);
753  first = false;
755  }
756 
757  return true;
758 }
759 
760 /*
761  * SpeculativeInsertionLockAcquire
762  *
763  * Insert a lock showing that the given transaction ID is inserting a tuple,
764  * but hasn't yet decided whether it's going to keep it. The lock can then be
765  * used to wait for the decision to go ahead with the insertion, or aborting
766  * it.
767  *
768  * The token is used to distinguish multiple insertions by the same
769  * transaction. It is returned to caller.
770  */
771 uint32
773 {
774  LOCKTAG tag;
775 
777 
778  /*
779  * Check for wrap-around. Zero means no token is held, so don't use that.
780  */
781  if (speculativeInsertionToken == 0)
783 
785 
786  (void) LockAcquire(&tag, ExclusiveLock, false, false);
787 
789 }
790 
791 /*
792  * SpeculativeInsertionLockRelease
793  *
794  * Delete the lock showing that the given transaction is speculatively
795  * inserting a tuple.
796  */
797 void
799 {
800  LOCKTAG tag;
801 
803 
804  LockRelease(&tag, ExclusiveLock, false);
805 }
806 
807 /*
808  * SpeculativeInsertionWait
809  *
810  * Wait for the specified transaction to finish or abort the insertion of a
811  * tuple.
812  */
813 void
815 {
816  LOCKTAG tag;
817 
819 
821  Assert(token != 0);
822 
823  (void) LockAcquire(&tag, ShareLock, false, false);
824  LockRelease(&tag, ShareLock, false);
825 }
826 
827 /*
828  * XactLockTableWaitErrorCb
829  * Error context callback for transaction lock waits.
830  */
831 static void
833 {
835 
836  /*
837  * We would like to print schema name too, but that would require a
838  * syscache lookup.
839  */
840  if (info->oper != XLTW_None &&
841  ItemPointerIsValid(info->ctid) && RelationIsValid(info->rel))
842  {
843  const char *cxt;
844 
845  switch (info->oper)
846  {
847  case XLTW_Update:
848  cxt = gettext_noop("while updating tuple (%u,%u) in relation \"%s\"");
849  break;
850  case XLTW_Delete:
851  cxt = gettext_noop("while deleting tuple (%u,%u) in relation \"%s\"");
852  break;
853  case XLTW_Lock:
854  cxt = gettext_noop("while locking tuple (%u,%u) in relation \"%s\"");
855  break;
856  case XLTW_LockUpdated:
857  cxt = gettext_noop("while locking updated version (%u,%u) of tuple in relation \"%s\"");
858  break;
859  case XLTW_InsertIndex:
860  cxt = gettext_noop("while inserting index tuple (%u,%u) in relation \"%s\"");
861  break;
863  cxt = gettext_noop("while checking uniqueness of tuple (%u,%u) in relation \"%s\"");
864  break;
865  case XLTW_FetchUpdated:
866  cxt = gettext_noop("while rechecking updated tuple (%u,%u) in relation \"%s\"");
867  break;
869  cxt = gettext_noop("while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"");
870  break;
871 
872  default:
873  return;
874  }
875 
876  errcontext(cxt,
880  }
881 }
882 
883 /*
884  * WaitForLockersMultiple
885  * Wait until no transaction holds locks that conflict with the given
886  * locktags at the given lockmode.
887  *
888  * To do this, obtain the current list of lockers, and wait on their VXIDs
889  * until they are finished.
890  *
891  * Note we don't try to acquire the locks on the given locktags, only the
892  * VXIDs and XIDs of their lock holders; if somebody grabs a conflicting lock
893  * on the objects after we obtained our initial list of lockers, we will not
894  * wait for them.
895  */
896 void
897 WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
898 {
899  List *holders = NIL;
900  ListCell *lc;
901  int total = 0;
902  int done = 0;
903 
904  /* Done if no locks to wait for */
905  if (locktags == NIL)
906  return;
907 
908  /* Collect the transactions we need to wait on */
909  foreach(lc, locktags)
910  {
911  LOCKTAG *locktag = lfirst(lc);
912  int count;
913 
914  holders = lappend(holders,
915  GetLockConflicts(locktag, lockmode,
916  progress ? &count : NULL));
917  if (progress)
918  total += count;
919  }
920 
921  if (progress)
923 
924  /*
925  * Note: GetLockConflicts() never reports our own xid, hence we need not
926  * check for that. Also, prepared xacts are reported and awaited.
927  */
928 
929  /* Finally wait for each such transaction to complete */
930  foreach(lc, holders)
931  {
932  VirtualTransactionId *lockholders = lfirst(lc);
933 
934  while (VirtualTransactionIdIsValid(*lockholders))
935  {
936  /* If requested, publish who we're going to wait for. */
937  if (progress)
938  {
939  PGPROC *holder = ProcNumberGetProc(lockholders->procNumber);
940 
941  if (holder)
943  holder->pid);
944  }
945  VirtualXactLock(*lockholders, true);
946  lockholders++;
947 
948  if (progress)
950  }
951  }
952  if (progress)
953  {
954  const int index[] = {
958  };
959  const int64 values[] = {
960  0, 0, 0
961  };
962 
964  }
965 
966  list_free_deep(holders);
967 }
968 
969 /*
970  * WaitForLockers
971  *
972  * Same as WaitForLockersMultiple, for a single lock tag.
973  */
974 void
975 WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress)
976 {
977  List *l;
978 
979  l = list_make1(&heaplocktag);
980  WaitForLockersMultiple(l, lockmode, progress);
981  list_free(l);
982 }
983 
984 
985 /*
986  * LockDatabaseObject
987  *
988  * Obtain a lock on a general object of the current database. Don't use
989  * this for shared objects (such as tablespaces). It's unwise to apply it
990  * to relations, also, since a lock taken this way will NOT conflict with
991  * locks taken via LockRelation and friends.
992  */
993 void
994 LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
995  LOCKMODE lockmode)
996 {
997  LOCKTAG tag;
998 
999  SET_LOCKTAG_OBJECT(tag,
1000  MyDatabaseId,
1001  classid,
1002  objid,
1003  objsubid);
1004 
1005  (void) LockAcquire(&tag, lockmode, false, false);
1006 
1007  /* Make sure syscaches are up-to-date with any changes we waited for */
1009 }
1010 
1011 /*
1012  * ConditionalLockDatabaseObject
1013  *
1014  * As above, but only lock if we can get the lock without blocking.
1015  * Returns true iff the lock was acquired.
1016  */
1017 bool
1018 ConditionalLockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
1019  LOCKMODE lockmode)
1020 {
1021  LOCKTAG tag;
1022  LOCALLOCK *locallock;
1024 
1025  SET_LOCKTAG_OBJECT(tag,
1026  MyDatabaseId,
1027  classid,
1028  objid,
1029  objsubid);
1030 
1031  res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock);
1032 
1033  if (res == LOCKACQUIRE_NOT_AVAIL)
1034  return false;
1035 
1036  /*
1037  * Now that we have the lock, check for invalidation messages; see notes
1038  * in LockRelationOid.
1039  */
1041  {
1043  MarkLockClear(locallock);
1044  }
1045 
1046  return true;
1047 }
1048 
1049 /*
1050  * UnlockDatabaseObject
1051  */
1052 void
1053 UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
1054  LOCKMODE lockmode)
1055 {
1056  LOCKTAG tag;
1057 
1058  SET_LOCKTAG_OBJECT(tag,
1059  MyDatabaseId,
1060  classid,
1061  objid,
1062  objsubid);
1063 
1064  LockRelease(&tag, lockmode, false);
1065 }
1066 
1067 /*
1068  * LockSharedObject
1069  *
1070  * Obtain a lock on a shared-across-databases object.
1071  */
1072 void
1073 LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1074  LOCKMODE lockmode)
1075 {
1076  LOCKTAG tag;
1077 
1078  SET_LOCKTAG_OBJECT(tag,
1079  InvalidOid,
1080  classid,
1081  objid,
1082  objsubid);
1083 
1084  (void) LockAcquire(&tag, lockmode, false, false);
1085 
1086  /* Make sure syscaches are up-to-date with any changes we waited for */
1088 }
1089 
1090 /*
1091  * ConditionalLockSharedObject
1092  *
1093  * As above, but only lock if we can get the lock without blocking.
1094  * Returns true iff the lock was acquired.
1095  */
1096 bool
1097 ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1098  LOCKMODE lockmode)
1099 {
1100  LOCKTAG tag;
1101  LOCALLOCK *locallock;
1103 
1104  SET_LOCKTAG_OBJECT(tag,
1105  InvalidOid,
1106  classid,
1107  objid,
1108  objsubid);
1109 
1110  res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock);
1111 
1112  if (res == LOCKACQUIRE_NOT_AVAIL)
1113  return false;
1114 
1115  /*
1116  * Now that we have the lock, check for invalidation messages; see notes
1117  * in LockRelationOid.
1118  */
1120  {
1122  MarkLockClear(locallock);
1123  }
1124 
1125  return true;
1126 }
1127 
1128 /*
1129  * UnlockSharedObject
1130  */
1131 void
1132 UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1133  LOCKMODE lockmode)
1134 {
1135  LOCKTAG tag;
1136 
1137  SET_LOCKTAG_OBJECT(tag,
1138  InvalidOid,
1139  classid,
1140  objid,
1141  objsubid);
1142 
1143  LockRelease(&tag, lockmode, false);
1144 }
1145 
1146 /*
1147  * LockSharedObjectForSession
1148  *
1149  * Obtain a session-level lock on a shared-across-databases object.
1150  * See LockRelationIdForSession for notes about session-level locks.
1151  */
1152 void
1153 LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
1154  LOCKMODE lockmode)
1155 {
1156  LOCKTAG tag;
1157 
1158  SET_LOCKTAG_OBJECT(tag,
1159  InvalidOid,
1160  classid,
1161  objid,
1162  objsubid);
1163 
1164  (void) LockAcquire(&tag, lockmode, true, false);
1165 }
1166 
1167 /*
1168  * UnlockSharedObjectForSession
1169  */
1170 void
1171 UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
1172  LOCKMODE lockmode)
1173 {
1174  LOCKTAG tag;
1175 
1176  SET_LOCKTAG_OBJECT(tag,
1177  InvalidOid,
1178  classid,
1179  objid,
1180  objsubid);
1181 
1182  LockRelease(&tag, lockmode, true);
1183 }
1184 
1185 /*
1186  * LockApplyTransactionForSession
1187  *
1188  * Obtain a session-level lock on a transaction being applied on a logical
1189  * replication subscriber. See LockRelationIdForSession for notes about
1190  * session-level locks.
1191  */
1192 void
1194  LOCKMODE lockmode)
1195 {
1196  LOCKTAG tag;
1197 
1199  MyDatabaseId,
1200  suboid,
1201  xid,
1202  objid);
1203 
1204  (void) LockAcquire(&tag, lockmode, true, false);
1205 }
1206 
1207 /*
1208  * UnlockApplyTransactionForSession
1209  */
1210 void
1212  LOCKMODE lockmode)
1213 {
1214  LOCKTAG tag;
1215 
1217  MyDatabaseId,
1218  suboid,
1219  xid,
1220  objid);
1221 
1222  LockRelease(&tag, lockmode, true);
1223 }
1224 
1225 /*
1226  * Append a description of a lockable object to buf.
1227  *
1228  * Ideally we would print names for the numeric values, but that requires
1229  * getting locks on system tables, which might cause problems since this is
1230  * typically used to report deadlock situations.
1231  */
1232 void
1234 {
1235  switch ((LockTagType) tag->locktag_type)
1236  {
1237  case LOCKTAG_RELATION:
1239  _("relation %u of database %u"),
1240  tag->locktag_field2,
1241  tag->locktag_field1);
1242  break;
1245  _("extension of relation %u of database %u"),
1246  tag->locktag_field2,
1247  tag->locktag_field1);
1248  break;
1251  _("pg_database.datfrozenxid of database %u"),
1252  tag->locktag_field1);
1253  break;
1254  case LOCKTAG_PAGE:
1256  _("page %u of relation %u of database %u"),
1257  tag->locktag_field3,
1258  tag->locktag_field2,
1259  tag->locktag_field1);
1260  break;
1261  case LOCKTAG_TUPLE:
1263  _("tuple (%u,%u) of relation %u of database %u"),
1264  tag->locktag_field3,
1265  tag->locktag_field4,
1266  tag->locktag_field2,
1267  tag->locktag_field1);
1268  break;
1269  case LOCKTAG_TRANSACTION:
1271  _("transaction %u"),
1272  tag->locktag_field1);
1273  break;
1276  _("virtual transaction %d/%u"),
1277  tag->locktag_field1,
1278  tag->locktag_field2);
1279  break;
1282  _("speculative token %u of transaction %u"),
1283  tag->locktag_field2,
1284  tag->locktag_field1);
1285  break;
1286  case LOCKTAG_OBJECT:
1288  _("object %u of class %u of database %u"),
1289  tag->locktag_field3,
1290  tag->locktag_field2,
1291  tag->locktag_field1);
1292  break;
1293  case LOCKTAG_USERLOCK:
1294  /* reserved for old contrib code, now on pgfoundry */
1296  _("user lock [%u,%u,%u]"),
1297  tag->locktag_field1,
1298  tag->locktag_field2,
1299  tag->locktag_field3);
1300  break;
1301  case LOCKTAG_ADVISORY:
1303  _("advisory lock [%u,%u,%u,%u]"),
1304  tag->locktag_field1,
1305  tag->locktag_field2,
1306  tag->locktag_field3,
1307  tag->locktag_field4);
1308  break;
1311  _("remote transaction %u of subscription %u of database %u"),
1312  tag->locktag_field3,
1313  tag->locktag_field2,
1314  tag->locktag_field1);
1315  break;
1316  default:
1318  _("unrecognized locktag type %d"),
1319  (int) tag->locktag_type);
1320  break;
1321  }
1322 }
1323 
1324 /*
1325  * GetLockNameFromTagType
1326  *
1327  * Given locktag type, return the corresponding lock name.
1328  */
1329 const char *
1331 {
1332  if (locktag_type > LOCKTAG_LAST_TYPE)
1333  return "???";
1334  return LockTagTypeNames[locktag_type];
1335 }
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
uint32 BlockNumber
Definition: block.h:31
static Datum values[MAXATTR]
Definition: bootstrap.c:150
unsigned short uint16
Definition: c.h:505
unsigned int uint32
Definition: c.h:506
#define gettext_noop(x)
Definition: c.h:1196
#define Assert(condition)
Definition: c.h:858
uint32 TransactionId
Definition: c.h:652
#define OidIsValid(objectId)
Definition: c.h:775
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:264
ErrorContextCallback * error_context_stack
Definition: elog.c:94
#define _(x)
Definition: elog.c:90
#define errcontext
Definition: elog.h:196
Oid MyDatabaseId
Definition: globals.c:92
#define token
Definition: indent_globs.h:126
void AcceptInvalidationMessages(void)
Definition: inval.c:806
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
static bool ItemPointerIsValid(const ItemPointerData *pointer)
Definition: itemptr.h:83
List * lappend(List *list, void *datum)
Definition: list.c:339
void list_free(List *list)
Definition: list.c:1546
void list_free_deep(List *list)
Definition: list.c:1560
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:151
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:657
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1073
bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:522
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:227
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:994
void UnlockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:310
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:1233
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
Definition: lmgr.c:814
bool ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1097
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1171
void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
Definition: lmgr.c:897
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:387
void RelationInitLockInfo(Relation relation)
Definition: lmgr.c:71
bool ConditionalLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:578
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
void LockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:244
void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:212
void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress)
Definition: lmgr.c:975
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:633
void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:558
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:616
uint32 SpeculativeInsertionLockAcquire(TransactionId xid)
Definition: lmgr.c:772
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:420
bool ConditionalXactLockTableWait(TransactionId xid)
Definition: lmgr.c:730
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:330
void UnlockApplyTransactionForSession(Oid suboid, TransactionId xid, uint16 objid, LOCKMODE lockmode)
Definition: lmgr.c:1211
void SpeculativeInsertionLockRelease(TransactionId xid)
Definition: lmgr.c:798
static void XactLockTableWaitErrorCb(void *arg)
Definition: lmgr.c:832
void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:503
bool ConditionalLockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:438
bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:347
const char * GetLockNameFromTagType(uint16 locktag_type)
Definition: lmgr.c:1330
static void SetLocktagRelationOid(LOCKTAG *tag, Oid relid)
Definition: lmgr.c:89
void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:538
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:400
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:275
static uint32 speculativeInsertionToken
Definition: lmgr.c:46
bool ConditionalLockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1018
void LockDatabaseFrozenIds(LOCKMODE lockmode)
Definition: lmgr.c:487
struct XactLockTableWaitInfo XactLockTableWaitInfo
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:470
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1132
void LockApplyTransactionForSession(Oid suboid, TransactionId xid, uint16 objid, LOCKMODE lockmode)
Definition: lmgr.c:1193
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1153
void LockRelationId(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:184
bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:363
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1053
int RelationExtensionLockWaiterCount(Relation relation)
Definition: lmgr.c:455
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:595
XLTW_Oper
Definition: lmgr.h:25
@ XLTW_FetchUpdated
Definition: lmgr.h:33
@ XLTW_None
Definition: lmgr.h:26
@ XLTW_Lock
Definition: lmgr.h:29
@ XLTW_Delete
Definition: lmgr.h:28
@ XLTW_InsertIndex
Definition: lmgr.h:31
@ XLTW_LockUpdated
Definition: lmgr.h:30
@ XLTW_RecheckExclusionConstr
Definition: lmgr.h:34
@ XLTW_Update
Definition: lmgr.h:27
@ XLTW_InsertIndexUnique
Definition: lmgr.h:32
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:756
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp)
Definition: lock.c:780
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode, bool orstronger)
Definition: lock.c:590
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2894
int LockWaiterCount(const LOCKTAG *locktag)
Definition: lock.c:4661
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1964
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
Definition: lock.c:4550
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:643
void MarkLockClear(LOCALLOCK *locallock)
Definition: lock.c:1802
#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag, dboid)
Definition: lock.h:199
#define SET_LOCKTAG_RELATION_EXTEND(locktag, dboid, reloid)
Definition: lock.h:190
LockTagType
Definition: lock.h:136
@ LOCKTAG_OBJECT
Definition: lock.h:145
@ LOCKTAG_RELATION_EXTEND
Definition: lock.h:138
@ LOCKTAG_RELATION
Definition: lock.h:137
@ LOCKTAG_TUPLE
Definition: lock.h:141
@ LOCKTAG_SPECULATIVE_TOKEN
Definition: lock.h:144
@ LOCKTAG_APPLY_TRANSACTION
Definition: lock.h:148
@ LOCKTAG_USERLOCK
Definition: lock.h:146
@ LOCKTAG_DATABASE_FROZEN_IDS
Definition: lock.h:139
@ LOCKTAG_VIRTUALTRANSACTION
Definition: lock.h:143
@ LOCKTAG_TRANSACTION
Definition: lock.h:142
@ LOCKTAG_PAGE
Definition: lock.h:140
@ LOCKTAG_ADVISORY
Definition: lock.h:147
#define SET_LOCKTAG_APPLY_TRANSACTION(locktag, dboid, suboid, xid, objid)
Definition: lock.h:282
#define VirtualTransactionIdIsValid(vxid)
Definition: lock.h:67
#define SET_LOCKTAG_TRANSACTION(locktag, xid)
Definition: lock.h:226
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:181
#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag, xid, token)
Definition: lock.h:247
#define LOCKTAG_LAST_TYPE
Definition: lock.h:152
#define SET_LOCKTAG_PAGE(locktag, dboid, reloid, blocknum)
Definition: lock.h:208
#define SET_LOCKTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
Definition: lock.h:217
#define SET_LOCKTAG_OBJECT(locktag, dboid, classoid, objoid, objsubid)
Definition: lock.h:262
LockAcquireResult
Definition: lock.h:500
@ LOCKACQUIRE_ALREADY_CLEAR
Definition: lock.h:504
@ LOCKACQUIRE_NOT_AVAIL
Definition: lock.h:501
int LOCKMODE
Definition: lockdefs.h:26
#define ExclusiveLock
Definition: lockdefs.h:42
#define ShareLock
Definition: lockdefs.h:40
const char *const LockTagTypeNames[]
Definition: lockfuncs.c:28
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:370
void * arg
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
#define list_make1(x1)
Definition: pg_list.h:212
static char * buf
Definition: pg_test_fsync.c:73
static int progress
Definition: pgbench.c:261
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
Definition: procarray.c:3142
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:1402
#define PROGRESS_WAITFOR_DONE
Definition: progress.h:118
#define PROGRESS_WAITFOR_TOTAL
Definition: progress.h:117
#define PROGRESS_WAITFOR_CURRENT_PID
Definition: progress.h:119
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define RelationIsValid(relation)
Definition: rel.h:478
void pg_usleep(long microsec)
Definition: signal.c:53
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
Definition: lock.h:165
uint8 locktag_type
Definition: lock.h:170
uint32 locktag_field3
Definition: lock.h:168
uint32 locktag_field1
Definition: lock.h:166
uint16 locktag_field4
Definition: lock.h:169
uint32 locktag_field2
Definition: lock.h:167
Definition: pg_list.h:54
LockRelId lockRelId
Definition: rel.h:46
Definition: rel.h:39
Oid relId
Definition: rel.h:40
Oid dbId
Definition: rel.h:41
Definition: proc.h:157
int pid
Definition: proc.h:177
LockInfoData rd_lockInfo
Definition: rel.h:114
Form_pg_class rd_rel
Definition: rel.h:111
ProcNumber procNumber
Definition: lock.h:61
ItemPointer ctid
Definition: lmgr.c:59
XLTW_Oper oper
Definition: lmgr.c:57
Relation rel
Definition: lmgr.c:58
Definition: type.h:95
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition: subtrans.c:163
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define TransactionIdIsValid(xid)
Definition: transam.h:41
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:439