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  if (LockHeldByMe(&tag, lockmode))
339  return true;
340 
341  if (orstronger)
342  {
343  LOCKMODE slockmode;
344 
345  for (slockmode = lockmode + 1;
346  slockmode <= MaxLockMode;
347  slockmode++)
348  {
349  if (LockHeldByMe(&tag, slockmode))
350  {
351 #ifdef NOT_USED
352  /* Sometimes this might be useful for debugging purposes */
353  elog(WARNING, "lock mode %s substituted for %s on relation %s",
354  GetLockmodeName(tag.locktag_lockmethodid, slockmode),
355  GetLockmodeName(tag.locktag_lockmethodid, lockmode),
356  RelationGetRelationName(relation));
357 #endif
358  return true;
359  }
360  }
361  }
362 
363  return false;
364 }
365 
366 /*
367  * LockHasWaitersRelation
368  *
369  * This is a function to check whether someone else is waiting for a
370  * lock which we are currently holding.
371  */
372 bool
374 {
375  LOCKTAG tag;
376 
378  relation->rd_lockInfo.lockRelId.dbId,
379  relation->rd_lockInfo.lockRelId.relId);
380 
381  return LockHasWaiters(&tag, lockmode, false);
382 }
383 
384 /*
385  * LockRelationIdForSession
386  *
387  * This routine grabs a session-level lock on the target relation. The
388  * session lock persists across transaction boundaries. It will be removed
389  * when UnlockRelationIdForSession() is called, or if an ereport(ERROR) occurs,
390  * or if the backend exits.
391  *
392  * Note that one should also grab a transaction-level lock on the rel
393  * in any transaction that actually uses the rel, to ensure that the
394  * relcache entry is up to date.
395  */
396 void
398 {
399  LOCKTAG tag;
400 
401  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
402 
403  (void) LockAcquire(&tag, lockmode, true, false);
404 }
405 
406 /*
407  * UnlockRelationIdForSession
408  */
409 void
411 {
412  LOCKTAG tag;
413 
414  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
415 
416  LockRelease(&tag, lockmode, true);
417 }
418 
419 /*
420  * LockRelationForExtension
421  *
422  * This lock tag is used to interlock addition of pages to relations.
423  * We need such locking because bufmgr/smgr definition of P_NEW is not
424  * race-condition-proof.
425  *
426  * We assume the caller is already holding some type of regular lock on
427  * the relation, so no AcceptInvalidationMessages call is needed here.
428  */
429 void
431 {
432  LOCKTAG tag;
433 
435  relation->rd_lockInfo.lockRelId.dbId,
436  relation->rd_lockInfo.lockRelId.relId);
437 
438  (void) LockAcquire(&tag, lockmode, false, false);
439 }
440 
441 /*
442  * ConditionalLockRelationForExtension
443  *
444  * As above, but only lock if we can get the lock without blocking.
445  * Returns true iff the lock was acquired.
446  */
447 bool
449 {
450  LOCKTAG tag;
451 
453  relation->rd_lockInfo.lockRelId.dbId,
454  relation->rd_lockInfo.lockRelId.relId);
455 
456  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
457 }
458 
459 /*
460  * RelationExtensionLockWaiterCount
461  *
462  * Count the number of processes waiting for the given relation extension lock.
463  */
464 int
466 {
467  LOCKTAG tag;
468 
470  relation->rd_lockInfo.lockRelId.dbId,
471  relation->rd_lockInfo.lockRelId.relId);
472 
473  return LockWaiterCount(&tag);
474 }
475 
476 /*
477  * UnlockRelationForExtension
478  */
479 void
481 {
482  LOCKTAG tag;
483 
485  relation->rd_lockInfo.lockRelId.dbId,
486  relation->rd_lockInfo.lockRelId.relId);
487 
488  LockRelease(&tag, lockmode, false);
489 }
490 
491 /*
492  * LockDatabaseFrozenIds
493  *
494  * This allows one backend per database to execute vac_update_datfrozenxid().
495  */
496 void
498 {
499  LOCKTAG tag;
500 
502 
503  (void) LockAcquire(&tag, lockmode, false, false);
504 }
505 
506 /*
507  * LockPage
508  *
509  * Obtain a page-level lock. This is currently used by some index access
510  * methods to lock individual index pages.
511  */
512 void
513 LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
514 {
515  LOCKTAG tag;
516 
517  SET_LOCKTAG_PAGE(tag,
518  relation->rd_lockInfo.lockRelId.dbId,
519  relation->rd_lockInfo.lockRelId.relId,
520  blkno);
521 
522  (void) LockAcquire(&tag, lockmode, false, false);
523 }
524 
525 /*
526  * ConditionalLockPage
527  *
528  * As above, but only lock if we can get the lock without blocking.
529  * Returns true iff the lock was acquired.
530  */
531 bool
533 {
534  LOCKTAG tag;
535 
536  SET_LOCKTAG_PAGE(tag,
537  relation->rd_lockInfo.lockRelId.dbId,
538  relation->rd_lockInfo.lockRelId.relId,
539  blkno);
540 
541  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
542 }
543 
544 /*
545  * UnlockPage
546  */
547 void
548 UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
549 {
550  LOCKTAG tag;
551 
552  SET_LOCKTAG_PAGE(tag,
553  relation->rd_lockInfo.lockRelId.dbId,
554  relation->rd_lockInfo.lockRelId.relId,
555  blkno);
556 
557  LockRelease(&tag, lockmode, false);
558 }
559 
560 /*
561  * LockTuple
562  *
563  * Obtain a tuple-level lock. This is used in a less-than-intuitive fashion
564  * because we can't afford to keep a separate lock in shared memory for every
565  * tuple. See heap_lock_tuple before using this!
566  */
567 void
568 LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
569 {
570  LOCKTAG tag;
571 
572  SET_LOCKTAG_TUPLE(tag,
573  relation->rd_lockInfo.lockRelId.dbId,
574  relation->rd_lockInfo.lockRelId.relId,
577 
578  (void) LockAcquire(&tag, lockmode, false, false);
579 }
580 
581 /*
582  * ConditionalLockTuple
583  *
584  * As above, but only lock if we can get the lock without blocking.
585  * Returns true iff the lock was acquired.
586  */
587 bool
589 {
590  LOCKTAG tag;
591 
592  SET_LOCKTAG_TUPLE(tag,
593  relation->rd_lockInfo.lockRelId.dbId,
594  relation->rd_lockInfo.lockRelId.relId,
597 
598  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
599 }
600 
601 /*
602  * UnlockTuple
603  */
604 void
605 UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
606 {
607  LOCKTAG tag;
608 
609  SET_LOCKTAG_TUPLE(tag,
610  relation->rd_lockInfo.lockRelId.dbId,
611  relation->rd_lockInfo.lockRelId.relId,
614 
615  LockRelease(&tag, lockmode, false);
616 }
617 
618 /*
619  * XactLockTableInsert
620  *
621  * Insert a lock showing that the given transaction ID is running ---
622  * this is done when an XID is acquired by a transaction or subtransaction.
623  * The lock can then be used to wait for the transaction to finish.
624  */
625 void
627 {
628  LOCKTAG tag;
629 
630  SET_LOCKTAG_TRANSACTION(tag, xid);
631 
632  (void) LockAcquire(&tag, ExclusiveLock, false, false);
633 }
634 
635 /*
636  * XactLockTableDelete
637  *
638  * Delete the lock showing that the given transaction ID is running.
639  * (This is never used for main transaction IDs; those locks are only
640  * released implicitly at transaction end. But we do use it for subtrans IDs.)
641  */
642 void
644 {
645  LOCKTAG tag;
646 
647  SET_LOCKTAG_TRANSACTION(tag, xid);
648 
649  LockRelease(&tag, ExclusiveLock, false);
650 }
651 
652 /*
653  * XactLockTableWait
654  *
655  * Wait for the specified transaction to commit or abort. If an operation
656  * is specified, an error context callback is set up. If 'oper' is passed as
657  * None, no error context callback is set up.
658  *
659  * Note that this does the right thing for subtransactions: if we wait on a
660  * subtransaction, we will exit as soon as it aborts or its top parent commits.
661  * It takes some extra work to ensure this, because to save on shared memory
662  * the XID lock of a subtransaction is released when it ends, whether
663  * successfully or unsuccessfully. So we have to check if it's "still running"
664  * and if so wait for its parent.
665  */
666 void
668  XLTW_Oper oper)
669 {
670  LOCKTAG tag;
673  bool first = true;
674 
675  /*
676  * If an operation is specified, set up our verbose error context
677  * callback.
678  */
679  if (oper != XLTW_None)
680  {
681  Assert(RelationIsValid(rel));
682  Assert(ItemPointerIsValid(ctid));
683 
684  info.rel = rel;
685  info.ctid = ctid;
686  info.oper = oper;
687 
689  callback.arg = &info;
690  callback.previous = error_context_stack;
692  }
693 
694  for (;;)
695  {
698 
699  SET_LOCKTAG_TRANSACTION(tag, xid);
700 
701  (void) LockAcquire(&tag, ShareLock, false, false);
702 
703  LockRelease(&tag, ShareLock, false);
704 
705  if (!TransactionIdIsInProgress(xid))
706  break;
707 
708  /*
709  * If the Xid belonged to a subtransaction, then the lock would have
710  * gone away as soon as it was finished; for correct tuple visibility,
711  * the right action is to wait on its parent transaction to go away.
712  * But instead of going levels up one by one, we can just wait for the
713  * topmost transaction to finish with the same end result, which also
714  * incurs less locktable traffic.
715  *
716  * Some uses of this function don't involve tuple visibility -- such
717  * as when building snapshots for logical decoding. It is possible to
718  * see a transaction in ProcArray before it registers itself in the
719  * locktable. The topmost transaction in that case is the same xid,
720  * so we try again after a short sleep. (Don't sleep the first time
721  * through, to avoid slowing down the normal case.)
722  */
723  if (!first)
724  pg_usleep(1000L);
725  first = false;
727  }
728 
729  if (oper != XLTW_None)
730  error_context_stack = callback.previous;
731 }
732 
733 /*
734  * ConditionalXactLockTableWait
735  *
736  * As above, but only lock if we can get the lock without blocking.
737  * Returns true if the lock was acquired.
738  */
739 bool
741 {
742  LOCKTAG tag;
743  bool first = true;
744 
745  for (;;)
746  {
749 
750  SET_LOCKTAG_TRANSACTION(tag, xid);
751 
752  if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
753  return false;
754 
755  LockRelease(&tag, ShareLock, false);
756 
757  if (!TransactionIdIsInProgress(xid))
758  break;
759 
760  /* See XactLockTableWait about this case */
761  if (!first)
762  pg_usleep(1000L);
763  first = false;
765  }
766 
767  return true;
768 }
769 
770 /*
771  * SpeculativeInsertionLockAcquire
772  *
773  * Insert a lock showing that the given transaction ID is inserting a tuple,
774  * but hasn't yet decided whether it's going to keep it. The lock can then be
775  * used to wait for the decision to go ahead with the insertion, or aborting
776  * it.
777  *
778  * The token is used to distinguish multiple insertions by the same
779  * transaction. It is returned to caller.
780  */
781 uint32
783 {
784  LOCKTAG tag;
785 
787 
788  /*
789  * Check for wrap-around. Zero means no token is held, so don't use that.
790  */
791  if (speculativeInsertionToken == 0)
793 
795 
796  (void) LockAcquire(&tag, ExclusiveLock, false, false);
797 
799 }
800 
801 /*
802  * SpeculativeInsertionLockRelease
803  *
804  * Delete the lock showing that the given transaction is speculatively
805  * inserting a tuple.
806  */
807 void
809 {
810  LOCKTAG tag;
811 
813 
814  LockRelease(&tag, ExclusiveLock, false);
815 }
816 
817 /*
818  * SpeculativeInsertionWait
819  *
820  * Wait for the specified transaction to finish or abort the insertion of a
821  * tuple.
822  */
823 void
825 {
826  LOCKTAG tag;
827 
829 
831  Assert(token != 0);
832 
833  (void) LockAcquire(&tag, ShareLock, false, false);
834  LockRelease(&tag, ShareLock, false);
835 }
836 
837 /*
838  * XactLockTableWaitErrorCb
839  * Error context callback for transaction lock waits.
840  */
841 static void
843 {
845 
846  /*
847  * We would like to print schema name too, but that would require a
848  * syscache lookup.
849  */
850  if (info->oper != XLTW_None &&
851  ItemPointerIsValid(info->ctid) && RelationIsValid(info->rel))
852  {
853  const char *cxt;
854 
855  switch (info->oper)
856  {
857  case XLTW_Update:
858  cxt = gettext_noop("while updating tuple (%u,%u) in relation \"%s\"");
859  break;
860  case XLTW_Delete:
861  cxt = gettext_noop("while deleting tuple (%u,%u) in relation \"%s\"");
862  break;
863  case XLTW_Lock:
864  cxt = gettext_noop("while locking tuple (%u,%u) in relation \"%s\"");
865  break;
866  case XLTW_LockUpdated:
867  cxt = gettext_noop("while locking updated version (%u,%u) of tuple in relation \"%s\"");
868  break;
869  case XLTW_InsertIndex:
870  cxt = gettext_noop("while inserting index tuple (%u,%u) in relation \"%s\"");
871  break;
873  cxt = gettext_noop("while checking uniqueness of tuple (%u,%u) in relation \"%s\"");
874  break;
875  case XLTW_FetchUpdated:
876  cxt = gettext_noop("while rechecking updated tuple (%u,%u) in relation \"%s\"");
877  break;
879  cxt = gettext_noop("while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"");
880  break;
881 
882  default:
883  return;
884  }
885 
886  errcontext(cxt,
890  }
891 }
892 
893 /*
894  * WaitForLockersMultiple
895  * Wait until no transaction holds locks that conflict with the given
896  * locktags at the given lockmode.
897  *
898  * To do this, obtain the current list of lockers, and wait on their VXIDs
899  * until they are finished.
900  *
901  * Note we don't try to acquire the locks on the given locktags, only the
902  * VXIDs and XIDs of their lock holders; if somebody grabs a conflicting lock
903  * on the objects after we obtained our initial list of lockers, we will not
904  * wait for them.
905  */
906 void
907 WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
908 {
909  List *holders = NIL;
910  ListCell *lc;
911  int total = 0;
912  int done = 0;
913 
914  /* Done if no locks to wait for */
915  if (locktags == NIL)
916  return;
917 
918  /* Collect the transactions we need to wait on */
919  foreach(lc, locktags)
920  {
921  LOCKTAG *locktag = lfirst(lc);
922  int count;
923 
924  holders = lappend(holders,
925  GetLockConflicts(locktag, lockmode,
926  progress ? &count : NULL));
927  if (progress)
928  total += count;
929  }
930 
931  if (progress)
933 
934  /*
935  * Note: GetLockConflicts() never reports our own xid, hence we need not
936  * check for that. Also, prepared xacts are reported and awaited.
937  */
938 
939  /* Finally wait for each such transaction to complete */
940  foreach(lc, holders)
941  {
942  VirtualTransactionId *lockholders = lfirst(lc);
943 
944  while (VirtualTransactionIdIsValid(*lockholders))
945  {
946  /* If requested, publish who we're going to wait for. */
947  if (progress)
948  {
949  PGPROC *holder = ProcNumberGetProc(lockholders->procNumber);
950 
951  if (holder)
953  holder->pid);
954  }
955  VirtualXactLock(*lockholders, true);
956  lockholders++;
957 
958  if (progress)
960  }
961  }
962  if (progress)
963  {
964  const int index[] = {
968  };
969  const int64 values[] = {
970  0, 0, 0
971  };
972 
974  }
975 
976  list_free_deep(holders);
977 }
978 
979 /*
980  * WaitForLockers
981  *
982  * Same as WaitForLockersMultiple, for a single lock tag.
983  */
984 void
985 WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress)
986 {
987  List *l;
988 
989  l = list_make1(&heaplocktag);
990  WaitForLockersMultiple(l, lockmode, progress);
991  list_free(l);
992 }
993 
994 
995 /*
996  * LockDatabaseObject
997  *
998  * Obtain a lock on a general object of the current database. Don't use
999  * this for shared objects (such as tablespaces). It's unwise to apply it
1000  * to relations, also, since a lock taken this way will NOT conflict with
1001  * locks taken via LockRelation and friends.
1002  */
1003 void
1004 LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
1005  LOCKMODE lockmode)
1006 {
1007  LOCKTAG tag;
1008 
1009  SET_LOCKTAG_OBJECT(tag,
1010  MyDatabaseId,
1011  classid,
1012  objid,
1013  objsubid);
1014 
1015  (void) LockAcquire(&tag, lockmode, false, false);
1016 
1017  /* Make sure syscaches are up-to-date with any changes we waited for */
1019 }
1020 
1021 /*
1022  * UnlockDatabaseObject
1023  */
1024 void
1025 UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
1026  LOCKMODE lockmode)
1027 {
1028  LOCKTAG tag;
1029 
1030  SET_LOCKTAG_OBJECT(tag,
1031  MyDatabaseId,
1032  classid,
1033  objid,
1034  objsubid);
1035 
1036  LockRelease(&tag, lockmode, false);
1037 }
1038 
1039 /*
1040  * LockSharedObject
1041  *
1042  * Obtain a lock on a shared-across-databases object.
1043  */
1044 void
1045 LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1046  LOCKMODE lockmode)
1047 {
1048  LOCKTAG tag;
1049 
1050  SET_LOCKTAG_OBJECT(tag,
1051  InvalidOid,
1052  classid,
1053  objid,
1054  objsubid);
1055 
1056  (void) LockAcquire(&tag, lockmode, false, false);
1057 
1058  /* Make sure syscaches are up-to-date with any changes we waited for */
1060 }
1061 
1062 /*
1063  * ConditionalLockSharedObject
1064  *
1065  * As above, but only lock if we can get the lock without blocking.
1066  * Returns true iff the lock was acquired.
1067  */
1068 bool
1069 ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1070  LOCKMODE lockmode)
1071 {
1072  LOCKTAG tag;
1073  LOCALLOCK *locallock;
1075 
1076  SET_LOCKTAG_OBJECT(tag,
1077  InvalidOid,
1078  classid,
1079  objid,
1080  objsubid);
1081 
1082  res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock);
1083 
1084  if (res == LOCKACQUIRE_NOT_AVAIL)
1085  return false;
1086 
1087  /*
1088  * Now that we have the lock, check for invalidation messages; see notes
1089  * in LockRelationOid.
1090  */
1092  {
1094  MarkLockClear(locallock);
1095  }
1096 
1097  return true;
1098 }
1099 
1100 /*
1101  * UnlockSharedObject
1102  */
1103 void
1104 UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
1105  LOCKMODE lockmode)
1106 {
1107  LOCKTAG tag;
1108 
1109  SET_LOCKTAG_OBJECT(tag,
1110  InvalidOid,
1111  classid,
1112  objid,
1113  objsubid);
1114 
1115  LockRelease(&tag, lockmode, false);
1116 }
1117 
1118 /*
1119  * LockSharedObjectForSession
1120  *
1121  * Obtain a session-level lock on a shared-across-databases object.
1122  * See LockRelationIdForSession for notes about session-level locks.
1123  */
1124 void
1125 LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
1126  LOCKMODE lockmode)
1127 {
1128  LOCKTAG tag;
1129 
1130  SET_LOCKTAG_OBJECT(tag,
1131  InvalidOid,
1132  classid,
1133  objid,
1134  objsubid);
1135 
1136  (void) LockAcquire(&tag, lockmode, true, false);
1137 }
1138 
1139 /*
1140  * UnlockSharedObjectForSession
1141  */
1142 void
1143 UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
1144  LOCKMODE lockmode)
1145 {
1146  LOCKTAG tag;
1147 
1148  SET_LOCKTAG_OBJECT(tag,
1149  InvalidOid,
1150  classid,
1151  objid,
1152  objsubid);
1153 
1154  LockRelease(&tag, lockmode, true);
1155 }
1156 
1157 /*
1158  * LockApplyTransactionForSession
1159  *
1160  * Obtain a session-level lock on a transaction being applied on a logical
1161  * replication subscriber. See LockRelationIdForSession for notes about
1162  * session-level locks.
1163  */
1164 void
1166  LOCKMODE lockmode)
1167 {
1168  LOCKTAG tag;
1169 
1171  MyDatabaseId,
1172  suboid,
1173  xid,
1174  objid);
1175 
1176  (void) LockAcquire(&tag, lockmode, true, false);
1177 }
1178 
1179 /*
1180  * UnlockApplyTransactionForSession
1181  */
1182 void
1184  LOCKMODE lockmode)
1185 {
1186  LOCKTAG tag;
1187 
1189  MyDatabaseId,
1190  suboid,
1191  xid,
1192  objid);
1193 
1194  LockRelease(&tag, lockmode, true);
1195 }
1196 
1197 /*
1198  * Append a description of a lockable object to buf.
1199  *
1200  * Ideally we would print names for the numeric values, but that requires
1201  * getting locks on system tables, which might cause problems since this is
1202  * typically used to report deadlock situations.
1203  */
1204 void
1206 {
1207  switch ((LockTagType) tag->locktag_type)
1208  {
1209  case LOCKTAG_RELATION:
1211  _("relation %u of database %u"),
1212  tag->locktag_field2,
1213  tag->locktag_field1);
1214  break;
1217  _("extension of relation %u of database %u"),
1218  tag->locktag_field2,
1219  tag->locktag_field1);
1220  break;
1223  _("pg_database.datfrozenxid of database %u"),
1224  tag->locktag_field1);
1225  break;
1226  case LOCKTAG_PAGE:
1228  _("page %u of relation %u of database %u"),
1229  tag->locktag_field3,
1230  tag->locktag_field2,
1231  tag->locktag_field1);
1232  break;
1233  case LOCKTAG_TUPLE:
1235  _("tuple (%u,%u) of relation %u of database %u"),
1236  tag->locktag_field3,
1237  tag->locktag_field4,
1238  tag->locktag_field2,
1239  tag->locktag_field1);
1240  break;
1241  case LOCKTAG_TRANSACTION:
1243  _("transaction %u"),
1244  tag->locktag_field1);
1245  break;
1248  _("virtual transaction %d/%u"),
1249  tag->locktag_field1,
1250  tag->locktag_field2);
1251  break;
1254  _("speculative token %u of transaction %u"),
1255  tag->locktag_field2,
1256  tag->locktag_field1);
1257  break;
1258  case LOCKTAG_OBJECT:
1260  _("object %u of class %u of database %u"),
1261  tag->locktag_field3,
1262  tag->locktag_field2,
1263  tag->locktag_field1);
1264  break;
1265  case LOCKTAG_USERLOCK:
1266  /* reserved for old contrib code, now on pgfoundry */
1268  _("user lock [%u,%u,%u]"),
1269  tag->locktag_field1,
1270  tag->locktag_field2,
1271  tag->locktag_field3);
1272  break;
1273  case LOCKTAG_ADVISORY:
1275  _("advisory lock [%u,%u,%u,%u]"),
1276  tag->locktag_field1,
1277  tag->locktag_field2,
1278  tag->locktag_field3,
1279  tag->locktag_field4);
1280  break;
1283  _("remote transaction %u of subscription %u of database %u"),
1284  tag->locktag_field3,
1285  tag->locktag_field2,
1286  tag->locktag_field1);
1287  break;
1288  default:
1290  _("unrecognized locktag type %d"),
1291  (int) tag->locktag_type);
1292  break;
1293  }
1294 }
1295 
1296 /*
1297  * GetLockNameFromTagType
1298  *
1299  * Given locktag type, return the corresponding lock name.
1300  */
1301 const char *
1303 {
1304  if (locktag_type > LOCKTAG_LAST_TYPE)
1305  return "???";
1306  return LockTagTypeNames[locktag_type];
1307 }
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:152
unsigned short uint16
Definition: c.h:492
unsigned int uint32
Definition: c.h:493
#define gettext_noop(x)
Definition: c.h:1183
uint32 TransactionId
Definition: c.h:639
#define OidIsValid(objectId)
Definition: c.h:762
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:243
ErrorContextCallback * error_context_stack
Definition: elog.c:94
#define _(x)
Definition: elog.c:90
#define errcontext
Definition: elog.h:196
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:224
Oid MyDatabaseId
Definition: globals.c:91
#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
Assert(fmt[strlen(fmt) - 1] !='\n')
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:667
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1045
bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:532
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:227
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1004
void UnlockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:310
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:1205
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
Definition: lmgr.c:824
bool ConditionalLockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1069
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1143
void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
Definition: lmgr.c:907
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:397
void RelationInitLockInfo(Relation relation)
Definition: lmgr.c:71
bool ConditionalLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:588
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:985
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:643
void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:568
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:626
uint32 SpeculativeInsertionLockAcquire(TransactionId xid)
Definition: lmgr.c:782
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:430
bool ConditionalXactLockTableWait(TransactionId xid)
Definition: lmgr.c:740
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:1183
void SpeculativeInsertionLockRelease(TransactionId xid)
Definition: lmgr.c:808
static void XactLockTableWaitErrorCb(void *arg)
Definition: lmgr.c:842
void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:513
bool ConditionalLockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:448
const char * GetLockNameFromTagType(uint16 locktag_type)
Definition: lmgr.c:1302
static void SetLocktagRelationOid(LOCKTAG *tag, Oid relid)
Definition: lmgr.c:89
void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:548
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:410
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:275
static uint32 speculativeInsertionToken
Definition: lmgr.c:46
void LockDatabaseFrozenIds(LOCKMODE lockmode)
Definition: lmgr.c:497
struct XactLockTableWaitInfo XactLockTableWaitInfo
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:480
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1104
void LockApplyTransactionForSession(Oid suboid, TransactionId xid, uint16 objid, LOCKMODE lockmode)
Definition: lmgr.c:1165
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1125
void LockRelationId(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:184
bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:373
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1025
int RelationExtensionLockWaiterCount(Relation relation)
Definition: lmgr.c:465
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:605
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:734
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp)
Definition: lock.c:758
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2872
int LockWaiterCount(const LOCKTAG *locktag)
Definition: lock.c:4639
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode)
Definition: lock.c:585
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1942
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
Definition: lock.c:4528
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:621
void MarkLockClear(LOCALLOCK *locallock)
Definition: lock.c:1780
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4038
#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
#define MaxLockMode
Definition: lockdefs.h:45
const char *const LockTagTypeNames[]
Definition: lockfuncs.c:29
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
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:3125
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:1390
#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: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
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:157
int pid
Definition: proc.h:178
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:433