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