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-2018, 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 "miscadmin.h"
23 #include "storage/lmgr.h"
24 #include "storage/procarray.h"
25 #include "utils/inval.h"
26 
27 
28 /*
29  * Per-backend counter for generating speculative insertion tokens.
30  *
31  * This may wrap around, but that's OK as it's only used for the short
32  * duration between inserting a tuple and checking that there are no (unique)
33  * constraint violations. It's theoretically possible that a backend sees a
34  * tuple that was speculatively inserted by another backend, but before it has
35  * started waiting on the token, the other backend completes its insertion,
36  * and then performs 2^32 unrelated insertions. And after all that, the
37  * first backend finally calls SpeculativeInsertionLockAcquire(), with the
38  * intention of waiting for the first insertion to complete, but ends up
39  * waiting for the latest unrelated insertion instead. Even then, nothing
40  * particularly bad happens: in the worst case they deadlock, causing one of
41  * the transactions to abort.
42  */
44 
45 
46 /*
47  * Struct to hold context info for transaction lock waits.
48  *
49  * 'oper' is the operation that needs to wait for the other transaction; 'rel'
50  * and 'ctid' specify the address of the tuple being waited for.
51  */
52 typedef struct XactLockTableWaitInfo
53 {
58 
59 static void XactLockTableWaitErrorCb(void *arg);
60 
61 /*
62  * RelationInitLockInfo
63  * Initializes the lock information in a relation descriptor.
64  *
65  * relcache.c must call this during creation of any reldesc.
66  */
67 void
69 {
70  Assert(RelationIsValid(relation));
72 
73  relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);
74 
75  if (relation->rd_rel->relisshared)
77  else
79 }
80 
81 /*
82  * SetLocktagRelationOid
83  * Set up a locktag for a relation, given only relation OID
84  */
85 static inline void
87 {
88  Oid dbid;
89 
90  if (IsSharedRelation(relid))
91  dbid = InvalidOid;
92  else
93  dbid = MyDatabaseId;
94 
95  SET_LOCKTAG_RELATION(*tag, dbid, relid);
96 }
97 
98 /*
99  * LockRelationOid
100  *
101  * Lock a relation given only its OID. This should generally be used
102  * before attempting to open the relation's relcache entry.
103  */
104 void
105 LockRelationOid(Oid relid, LOCKMODE lockmode)
106 {
107  LOCKTAG tag;
108  LockAcquireResult res;
109 
110  SetLocktagRelationOid(&tag, relid);
111 
112  res = LockAcquire(&tag, lockmode, false, false);
113 
114  /*
115  * Now that we have the lock, check for invalidation messages, so that we
116  * will update or flush any stale relcache entry before we try to use it.
117  * RangeVarGetRelid() specifically relies on us for this. We can skip
118  * this in the not-uncommon case that we already had the same type of lock
119  * being requested, since then no one else could have modified the
120  * relcache entry in an undesirable way. (In the case where our own xact
121  * modifies the rel, the relcache update happens via
122  * CommandCounterIncrement, not here.)
123  */
124  if (res != LOCKACQUIRE_ALREADY_HELD)
126 }
127 
128 /*
129  * ConditionalLockRelationOid
130  *
131  * As above, but only lock if we can get the lock without blocking.
132  * Returns true iff the lock was acquired.
133  *
134  * NOTE: we do not currently need conditional versions of all the
135  * LockXXX routines in this file, but they could easily be added if needed.
136  */
137 bool
139 {
140  LOCKTAG tag;
141  LockAcquireResult res;
142 
143  SetLocktagRelationOid(&tag, relid);
144 
145  res = LockAcquire(&tag, lockmode, false, true);
146 
147  if (res == LOCKACQUIRE_NOT_AVAIL)
148  return false;
149 
150  /*
151  * Now that we have the lock, check for invalidation messages; see notes
152  * in LockRelationOid.
153  */
154  if (res != LOCKACQUIRE_ALREADY_HELD)
156 
157  return true;
158 }
159 
160 /*
161  * UnlockRelationId
162  *
163  * Unlock, given a LockRelId. This is preferred over UnlockRelationOid
164  * for speed reasons.
165  */
166 void
168 {
169  LOCKTAG tag;
170 
171  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
172 
173  LockRelease(&tag, lockmode, false);
174 }
175 
176 /*
177  * UnlockRelationOid
178  *
179  * Unlock, given only a relation Oid. Use UnlockRelationId if you can.
180  */
181 void
183 {
184  LOCKTAG tag;
185 
186  SetLocktagRelationOid(&tag, relid);
187 
188  LockRelease(&tag, lockmode, false);
189 }
190 
191 /*
192  * LockRelation
193  *
194  * This is a convenience routine for acquiring an additional lock on an
195  * already-open relation. Never try to do "relation_open(foo, NoLock)"
196  * and then lock with this.
197  */
198 void
199 LockRelation(Relation relation, LOCKMODE lockmode)
200 {
201  LOCKTAG tag;
202  LockAcquireResult res;
203 
205  relation->rd_lockInfo.lockRelId.dbId,
206  relation->rd_lockInfo.lockRelId.relId);
207 
208  res = LockAcquire(&tag, lockmode, false, false);
209 
210  /*
211  * Now that we have the lock, check for invalidation messages; see notes
212  * in LockRelationOid.
213  */
214  if (res != LOCKACQUIRE_ALREADY_HELD)
216 }
217 
218 /*
219  * ConditionalLockRelation
220  *
221  * This is a convenience routine for acquiring an additional lock on an
222  * already-open relation. Never try to do "relation_open(foo, NoLock)"
223  * and then lock with this.
224  */
225 bool
227 {
228  LOCKTAG tag;
229  LockAcquireResult res;
230 
232  relation->rd_lockInfo.lockRelId.dbId,
233  relation->rd_lockInfo.lockRelId.relId);
234 
235  res = LockAcquire(&tag, lockmode, false, true);
236 
237  if (res == LOCKACQUIRE_NOT_AVAIL)
238  return false;
239 
240  /*
241  * Now that we have the lock, check for invalidation messages; see notes
242  * in LockRelationOid.
243  */
244  if (res != LOCKACQUIRE_ALREADY_HELD)
246 
247  return true;
248 }
249 
250 /*
251  * UnlockRelation
252  *
253  * This is a convenience routine for unlocking a relation without also
254  * closing it.
255  */
256 void
257 UnlockRelation(Relation relation, LOCKMODE lockmode)
258 {
259  LOCKTAG tag;
260 
262  relation->rd_lockInfo.lockRelId.dbId,
263  relation->rd_lockInfo.lockRelId.relId);
264 
265  LockRelease(&tag, lockmode, false);
266 }
267 
268 /*
269  * LockHasWaitersRelation
270  *
271  * This is a function to check whether someone else is waiting for a
272  * lock which we are currently holding.
273  */
274 bool
276 {
277  LOCKTAG tag;
278 
280  relation->rd_lockInfo.lockRelId.dbId,
281  relation->rd_lockInfo.lockRelId.relId);
282 
283  return LockHasWaiters(&tag, lockmode, false);
284 }
285 
286 /*
287  * LockRelationIdForSession
288  *
289  * This routine grabs a session-level lock on the target relation. The
290  * session lock persists across transaction boundaries. It will be removed
291  * when UnlockRelationIdForSession() is called, or if an ereport(ERROR) occurs,
292  * or if the backend exits.
293  *
294  * Note that one should also grab a transaction-level lock on the rel
295  * in any transaction that actually uses the rel, to ensure that the
296  * relcache entry is up to date.
297  */
298 void
300 {
301  LOCKTAG tag;
302 
303  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
304 
305  (void) LockAcquire(&tag, lockmode, true, false);
306 }
307 
308 /*
309  * UnlockRelationIdForSession
310  */
311 void
313 {
314  LOCKTAG tag;
315 
316  SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
317 
318  LockRelease(&tag, lockmode, true);
319 }
320 
321 /*
322  * LockRelationForExtension
323  *
324  * This lock tag is used to interlock addition of pages to relations.
325  * We need such locking because bufmgr/smgr definition of P_NEW is not
326  * race-condition-proof.
327  *
328  * We assume the caller is already holding some type of regular lock on
329  * the relation, so no AcceptInvalidationMessages call is needed here.
330  */
331 void
333 {
334  LOCKTAG tag;
335 
337  relation->rd_lockInfo.lockRelId.dbId,
338  relation->rd_lockInfo.lockRelId.relId);
339 
340  (void) LockAcquire(&tag, lockmode, false, false);
341 }
342 
343 /*
344  * ConditionalLockRelationForExtension
345  *
346  * As above, but only lock if we can get the lock without blocking.
347  * Returns true iff the lock was acquired.
348  */
349 bool
351 {
352  LOCKTAG tag;
353 
355  relation->rd_lockInfo.lockRelId.dbId,
356  relation->rd_lockInfo.lockRelId.relId);
357 
358  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
359 }
360 
361 /*
362  * RelationExtensionLockWaiterCount
363  *
364  * Count the number of processes waiting for the given relation extension lock.
365  */
366 int
368 {
369  LOCKTAG tag;
370 
372  relation->rd_lockInfo.lockRelId.dbId,
373  relation->rd_lockInfo.lockRelId.relId);
374 
375  return LockWaiterCount(&tag);
376 }
377 
378 /*
379  * UnlockRelationForExtension
380  */
381 void
383 {
384  LOCKTAG tag;
385 
387  relation->rd_lockInfo.lockRelId.dbId,
388  relation->rd_lockInfo.lockRelId.relId);
389 
390  LockRelease(&tag, lockmode, false);
391 }
392 
393 /*
394  * LockPage
395  *
396  * Obtain a page-level lock. This is currently used by some index access
397  * methods to lock individual index pages.
398  */
399 void
400 LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
401 {
402  LOCKTAG tag;
403 
404  SET_LOCKTAG_PAGE(tag,
405  relation->rd_lockInfo.lockRelId.dbId,
406  relation->rd_lockInfo.lockRelId.relId,
407  blkno);
408 
409  (void) LockAcquire(&tag, lockmode, false, false);
410 }
411 
412 /*
413  * ConditionalLockPage
414  *
415  * As above, but only lock if we can get the lock without blocking.
416  * Returns true iff the lock was acquired.
417  */
418 bool
420 {
421  LOCKTAG tag;
422 
423  SET_LOCKTAG_PAGE(tag,
424  relation->rd_lockInfo.lockRelId.dbId,
425  relation->rd_lockInfo.lockRelId.relId,
426  blkno);
427 
428  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
429 }
430 
431 /*
432  * UnlockPage
433  */
434 void
435 UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
436 {
437  LOCKTAG tag;
438 
439  SET_LOCKTAG_PAGE(tag,
440  relation->rd_lockInfo.lockRelId.dbId,
441  relation->rd_lockInfo.lockRelId.relId,
442  blkno);
443 
444  LockRelease(&tag, lockmode, false);
445 }
446 
447 /*
448  * LockTuple
449  *
450  * Obtain a tuple-level lock. This is used in a less-than-intuitive fashion
451  * because we can't afford to keep a separate lock in shared memory for every
452  * tuple. See heap_lock_tuple before using this!
453  */
454 void
455 LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
456 {
457  LOCKTAG tag;
458 
459  SET_LOCKTAG_TUPLE(tag,
460  relation->rd_lockInfo.lockRelId.dbId,
461  relation->rd_lockInfo.lockRelId.relId,
464 
465  (void) LockAcquire(&tag, lockmode, false, false);
466 }
467 
468 /*
469  * ConditionalLockTuple
470  *
471  * As above, but only lock if we can get the lock without blocking.
472  * Returns true iff the lock was acquired.
473  */
474 bool
476 {
477  LOCKTAG tag;
478 
479  SET_LOCKTAG_TUPLE(tag,
480  relation->rd_lockInfo.lockRelId.dbId,
481  relation->rd_lockInfo.lockRelId.relId,
484 
485  return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
486 }
487 
488 /*
489  * UnlockTuple
490  */
491 void
492 UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
493 {
494  LOCKTAG tag;
495 
496  SET_LOCKTAG_TUPLE(tag,
497  relation->rd_lockInfo.lockRelId.dbId,
498  relation->rd_lockInfo.lockRelId.relId,
501 
502  LockRelease(&tag, lockmode, false);
503 }
504 
505 /*
506  * XactLockTableInsert
507  *
508  * Insert a lock showing that the given transaction ID is running ---
509  * this is done when an XID is acquired by a transaction or subtransaction.
510  * The lock can then be used to wait for the transaction to finish.
511  */
512 void
514 {
515  LOCKTAG tag;
516 
517  SET_LOCKTAG_TRANSACTION(tag, xid);
518 
519  (void) LockAcquire(&tag, ExclusiveLock, false, false);
520 }
521 
522 /*
523  * XactLockTableDelete
524  *
525  * Delete the lock showing that the given transaction ID is running.
526  * (This is never used for main transaction IDs; those locks are only
527  * released implicitly at transaction end. But we do use it for subtrans IDs.)
528  */
529 void
531 {
532  LOCKTAG tag;
533 
534  SET_LOCKTAG_TRANSACTION(tag, xid);
535 
536  LockRelease(&tag, ExclusiveLock, false);
537 }
538 
539 /*
540  * XactLockTableWait
541  *
542  * Wait for the specified transaction to commit or abort. If an operation
543  * is specified, an error context callback is set up. If 'oper' is passed as
544  * None, no error context callback is set up.
545  *
546  * Note that this does the right thing for subtransactions: if we wait on a
547  * subtransaction, we will exit as soon as it aborts or its top parent commits.
548  * It takes some extra work to ensure this, because to save on shared memory
549  * the XID lock of a subtransaction is released when it ends, whether
550  * successfully or unsuccessfully. So we have to check if it's "still running"
551  * and if so wait for its parent.
552  */
553 void
555  XLTW_Oper oper)
556 {
557  LOCKTAG tag;
560  bool first = true;
561 
562  /*
563  * If an operation is specified, set up our verbose error context
564  * callback.
565  */
566  if (oper != XLTW_None)
567  {
568  Assert(RelationIsValid(rel));
569  Assert(ItemPointerIsValid(ctid));
570 
571  info.rel = rel;
572  info.ctid = ctid;
573  info.oper = oper;
574 
576  callback.arg = &info;
577  callback.previous = error_context_stack;
579  }
580 
581  for (;;)
582  {
585 
586  SET_LOCKTAG_TRANSACTION(tag, xid);
587 
588  (void) LockAcquire(&tag, ShareLock, false, false);
589 
590  LockRelease(&tag, ShareLock, false);
591 
592  if (!TransactionIdIsInProgress(xid))
593  break;
594 
595  /*
596  * If the Xid belonged to a subtransaction, then the lock would have
597  * gone away as soon as it was finished; for correct tuple visibility,
598  * the right action is to wait on its parent transaction to go away.
599  * But instead of going levels up one by one, we can just wait for the
600  * topmost transaction to finish with the same end result, which also
601  * incurs less locktable traffic.
602  *
603  * Some uses of this function don't involve tuple visibility -- such
604  * as when building snapshots for logical decoding. It is possible to
605  * see a transaction in ProcArray before it registers itself in the
606  * locktable. The topmost transaction in that case is the same xid,
607  * so we try again after a short sleep. (Don't sleep the first time
608  * through, to avoid slowing down the normal case.)
609  */
610  if (!first)
611  pg_usleep(1000L);
612  first = false;
614  }
615 
616  if (oper != XLTW_None)
617  error_context_stack = callback.previous;
618 }
619 
620 /*
621  * ConditionalXactLockTableWait
622  *
623  * As above, but only lock if we can get the lock without blocking.
624  * Returns true if the lock was acquired.
625  */
626 bool
628 {
629  LOCKTAG tag;
630  bool first = true;
631 
632  for (;;)
633  {
636 
637  SET_LOCKTAG_TRANSACTION(tag, xid);
638 
639  if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
640  return false;
641 
642  LockRelease(&tag, ShareLock, false);
643 
644  if (!TransactionIdIsInProgress(xid))
645  break;
646 
647  /* See XactLockTableWait about this case */
648  if (!first)
649  pg_usleep(1000L);
650  first = false;
652  }
653 
654  return true;
655 }
656 
657 /*
658  * SpeculativeInsertionLockAcquire
659  *
660  * Insert a lock showing that the given transaction ID is inserting a tuple,
661  * but hasn't yet decided whether it's going to keep it. The lock can then be
662  * used to wait for the decision to go ahead with the insertion, or aborting
663  * it.
664  *
665  * The token is used to distinguish multiple insertions by the same
666  * transaction. It is returned to caller.
667  */
668 uint32
670 {
671  LOCKTAG tag;
672 
674 
675  /*
676  * Check for wrap-around. Zero means no token is held, so don't use that.
677  */
678  if (speculativeInsertionToken == 0)
680 
682 
683  (void) LockAcquire(&tag, ExclusiveLock, false, false);
684 
686 }
687 
688 /*
689  * SpeculativeInsertionLockRelease
690  *
691  * Delete the lock showing that the given transaction is speculatively
692  * inserting a tuple.
693  */
694 void
696 {
697  LOCKTAG tag;
698 
700 
701  LockRelease(&tag, ExclusiveLock, false);
702 }
703 
704 /*
705  * SpeculativeInsertionWait
706  *
707  * Wait for the specified transaction to finish or abort the insertion of a
708  * tuple.
709  */
710 void
712 {
713  LOCKTAG tag;
714 
715  SET_LOCKTAG_SPECULATIVE_INSERTION(tag, xid, token);
716 
718  Assert(token != 0);
719 
720  (void) LockAcquire(&tag, ShareLock, false, false);
721  LockRelease(&tag, ShareLock, false);
722 }
723 
724 /*
725  * XactLockTableWaitErrorContextCb
726  * Error context callback for transaction lock waits.
727  */
728 static void
730 {
732 
733  /*
734  * We would like to print schema name too, but that would require a
735  * syscache lookup.
736  */
737  if (info->oper != XLTW_None &&
738  ItemPointerIsValid(info->ctid) && RelationIsValid(info->rel))
739  {
740  const char *cxt;
741 
742  switch (info->oper)
743  {
744  case XLTW_Update:
745  cxt = gettext_noop("while updating tuple (%u,%u) in relation \"%s\"");
746  break;
747  case XLTW_Delete:
748  cxt = gettext_noop("while deleting tuple (%u,%u) in relation \"%s\"");
749  break;
750  case XLTW_Lock:
751  cxt = gettext_noop("while locking tuple (%u,%u) in relation \"%s\"");
752  break;
753  case XLTW_LockUpdated:
754  cxt = gettext_noop("while locking updated version (%u,%u) of tuple in relation \"%s\"");
755  break;
756  case XLTW_InsertIndex:
757  cxt = gettext_noop("while inserting index tuple (%u,%u) in relation \"%s\"");
758  break;
760  cxt = gettext_noop("while checking uniqueness of tuple (%u,%u) in relation \"%s\"");
761  break;
762  case XLTW_FetchUpdated:
763  cxt = gettext_noop("while rechecking updated tuple (%u,%u) in relation \"%s\"");
764  break;
766  cxt = gettext_noop("while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"");
767  break;
768 
769  default:
770  return;
771  }
772 
773  errcontext(cxt,
777  }
778 }
779 
780 /*
781  * WaitForLockersMultiple
782  * Wait until no transaction holds locks that conflict with the given
783  * locktags at the given lockmode.
784  *
785  * To do this, obtain the current list of lockers, and wait on their VXIDs
786  * until they are finished.
787  *
788  * Note we don't try to acquire the locks on the given locktags, only the VXIDs
789  * of its lock holders; if somebody grabs a conflicting lock on the objects
790  * after we obtained our initial list of lockers, we will not wait for them.
791  */
792 void
794 {
795  List *holders = NIL;
796  ListCell *lc;
797 
798  /* Done if no locks to wait for */
799  if (list_length(locktags) == 0)
800  return;
801 
802  /* Collect the transactions we need to wait on */
803  foreach(lc, locktags)
804  {
805  LOCKTAG *locktag = lfirst(lc);
806 
807  holders = lappend(holders, GetLockConflicts(locktag, lockmode));
808  }
809 
810  /*
811  * Note: GetLockConflicts() never reports our own xid, hence we need not
812  * check for that. Also, prepared xacts are not reported, which is fine
813  * since they certainly aren't going to do anything anymore.
814  */
815 
816  /* Finally wait for each such transaction to complete */
817  foreach(lc, holders)
818  {
819  VirtualTransactionId *lockholders = lfirst(lc);
820 
821  while (VirtualTransactionIdIsValid(*lockholders))
822  {
823  VirtualXactLock(*lockholders, true);
824  lockholders++;
825  }
826  }
827 
828  list_free_deep(holders);
829 }
830 
831 /*
832  * WaitForLockers
833  *
834  * Same as WaitForLockersMultiple, for a single lock tag.
835  */
836 void
837 WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
838 {
839  List *l;
840 
841  l = list_make1(&heaplocktag);
842  WaitForLockersMultiple(l, lockmode);
843  list_free(l);
844 }
845 
846 
847 /*
848  * LockDatabaseObject
849  *
850  * Obtain a lock on a general object of the current database. Don't use
851  * this for shared objects (such as tablespaces). It's unwise to apply it
852  * to relations, also, since a lock taken this way will NOT conflict with
853  * locks taken via LockRelation and friends.
854  */
855 void
856 LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
857  LOCKMODE lockmode)
858 {
859  LOCKTAG tag;
860 
861  SET_LOCKTAG_OBJECT(tag,
862  MyDatabaseId,
863  classid,
864  objid,
865  objsubid);
866 
867  (void) LockAcquire(&tag, lockmode, false, false);
868 
869  /* Make sure syscaches are up-to-date with any changes we waited for */
871 }
872 
873 /*
874  * UnlockDatabaseObject
875  */
876 void
877 UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
878  LOCKMODE lockmode)
879 {
880  LOCKTAG tag;
881 
882  SET_LOCKTAG_OBJECT(tag,
883  MyDatabaseId,
884  classid,
885  objid,
886  objsubid);
887 
888  LockRelease(&tag, lockmode, false);
889 }
890 
891 /*
892  * LockSharedObject
893  *
894  * Obtain a lock on a shared-across-databases object.
895  */
896 void
897 LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
898  LOCKMODE lockmode)
899 {
900  LOCKTAG tag;
901 
902  SET_LOCKTAG_OBJECT(tag,
903  InvalidOid,
904  classid,
905  objid,
906  objsubid);
907 
908  (void) LockAcquire(&tag, lockmode, false, false);
909 
910  /* Make sure syscaches are up-to-date with any changes we waited for */
912 }
913 
914 /*
915  * UnlockSharedObject
916  */
917 void
918 UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
919  LOCKMODE lockmode)
920 {
921  LOCKTAG tag;
922 
923  SET_LOCKTAG_OBJECT(tag,
924  InvalidOid,
925  classid,
926  objid,
927  objsubid);
928 
929  LockRelease(&tag, lockmode, false);
930 }
931 
932 /*
933  * LockSharedObjectForSession
934  *
935  * Obtain a session-level lock on a shared-across-databases object.
936  * See LockRelationIdForSession for notes about session-level locks.
937  */
938 void
939 LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
940  LOCKMODE lockmode)
941 {
942  LOCKTAG tag;
943 
944  SET_LOCKTAG_OBJECT(tag,
945  InvalidOid,
946  classid,
947  objid,
948  objsubid);
949 
950  (void) LockAcquire(&tag, lockmode, true, false);
951 }
952 
953 /*
954  * UnlockSharedObjectForSession
955  */
956 void
957 UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
958  LOCKMODE lockmode)
959 {
960  LOCKTAG tag;
961 
962  SET_LOCKTAG_OBJECT(tag,
963  InvalidOid,
964  classid,
965  objid,
966  objsubid);
967 
968  LockRelease(&tag, lockmode, true);
969 }
970 
971 
972 /*
973  * Append a description of a lockable object to buf.
974  *
975  * Ideally we would print names for the numeric values, but that requires
976  * getting locks on system tables, which might cause problems since this is
977  * typically used to report deadlock situations.
978  */
979 void
981 {
982  switch ((LockTagType) tag->locktag_type)
983  {
984  case LOCKTAG_RELATION:
985  appendStringInfo(buf,
986  _("relation %u of database %u"),
987  tag->locktag_field2,
988  tag->locktag_field1);
989  break;
991  appendStringInfo(buf,
992  _("extension of relation %u of database %u"),
993  tag->locktag_field2,
994  tag->locktag_field1);
995  break;
996  case LOCKTAG_PAGE:
997  appendStringInfo(buf,
998  _("page %u of relation %u of database %u"),
999  tag->locktag_field3,
1000  tag->locktag_field2,
1001  tag->locktag_field1);
1002  break;
1003  case LOCKTAG_TUPLE:
1004  appendStringInfo(buf,
1005  _("tuple (%u,%u) of relation %u of database %u"),
1006  tag->locktag_field3,
1007  tag->locktag_field4,
1008  tag->locktag_field2,
1009  tag->locktag_field1);
1010  break;
1011  case LOCKTAG_TRANSACTION:
1012  appendStringInfo(buf,
1013  _("transaction %u"),
1014  tag->locktag_field1);
1015  break;
1017  appendStringInfo(buf,
1018  _("virtual transaction %d/%u"),
1019  tag->locktag_field1,
1020  tag->locktag_field2);
1021  break;
1023  appendStringInfo(buf,
1024  _("speculative token %u of transaction %u"),
1025  tag->locktag_field2,
1026  tag->locktag_field1);
1027  break;
1028  case LOCKTAG_OBJECT:
1029  appendStringInfo(buf,
1030  _("object %u of class %u of database %u"),
1031  tag->locktag_field3,
1032  tag->locktag_field2,
1033  tag->locktag_field1);
1034  break;
1035  case LOCKTAG_USERLOCK:
1036  /* reserved for old contrib code, now on pgfoundry */
1037  appendStringInfo(buf,
1038  _("user lock [%u,%u,%u]"),
1039  tag->locktag_field1,
1040  tag->locktag_field2,
1041  tag->locktag_field3);
1042  break;
1043  case LOCKTAG_ADVISORY:
1044  appendStringInfo(buf,
1045  _("advisory lock [%u,%u,%u,%u]"),
1046  tag->locktag_field1,
1047  tag->locktag_field2,
1048  tag->locktag_field3,
1049  tag->locktag_field4);
1050  break;
1051  default:
1052  appendStringInfo(buf,
1053  _("unrecognized locktag type %d"),
1054  (int) tag->locktag_type);
1055  break;
1056  }
1057 }
1058 
1059 /*
1060  * GetLockNameFromTagType
1061  *
1062  * Given locktag type, return the corresponding lock name.
1063  */
1064 const char *
1066 {
1067  if (locktag_type > LOCKTAG_LAST_TYPE)
1068  return "???";
1069  return LockTagTypeNames[locktag_type];
1070 }
#define SET_LOCKTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
Definition: lock.h:217
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:60
#define NIL
Definition: pg_list.h:69
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:138
Relation rel
Definition: lmgr.c:55
bool ConditionalLockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:350
LockRelId lockRelId
Definition: rel.h:44
void SpeculativeInsertionLockRelease(TransactionId xid)
Definition: lmgr.c:695
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:683
void AcceptInvalidationMessages(void)
Definition: inval.c:679
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
uint32 TransactionId
Definition: c.h:463
int RelationExtensionLockWaiterCount(Relation relation)
Definition: lmgr.c:367
void UnlockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:257
int LOCKMODE
Definition: lockdefs.h:26
static void SetLocktagRelationOid(LOCKTAG *tag, Oid relid)
Definition: lmgr.c:86
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition: subtrans.c:150
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:182
void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:167
#define ExclusiveLock
Definition: lockdefs.h:44
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:999
Oid dbId
Definition: rel.h:39
Definition: lock.h:178
#define gettext_noop(x)
Definition: c.h:1025
uint32 SpeculativeInsertionLockAcquire(TransactionId xid)
Definition: lmgr.c:669
uint32 BlockNumber
Definition: block.h:31
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
#define OidIsValid(objectId)
Definition: c.h:594
void list_free_deep(List *list)
Definition: list.c:1147
XLTW_Oper oper
Definition: lmgr.c:54
bool ConditionalLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:475
bool ConditionalXactLockTableWait(TransactionId xid)
Definition: lmgr.c:627
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:939
uint16 locktag_field4
Definition: lock.h:183
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
Definition: lock.c:4291
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define list_make1(x1)
Definition: pg_list.h:139
void pg_usleep(long microsec)
Definition: signal.c:53
unsigned short uint16
Definition: c.h:313
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:312
Definition: lmgr.h:26
Definition: rel.h:36
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:918
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:299
#define RelationIsValid(relation)
Definition: rel.h:398
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:980
void RelationInitLockInfo(Relation relation)
Definition: lmgr.c:68
void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:400
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
Definition: lmgr.c:711
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:957
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:193
LockInfoData rd_lockInfo
Definition: rel.h:117
static char * buf
Definition: pg_test_fsync.c:67
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:856
uint32 locktag_field2
Definition: lock.h:181
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:226
#define RelationGetRelationName(relation)
Definition: rel.h:445
unsigned int uint32
Definition: c.h:314
ItemPointer ctid
Definition: lmgr.c:56
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:405
#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag, xid, token)
Definition: lock.h:241
static void XactLockTableWaitErrorCb(void *arg)
Definition: lmgr.c:729
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:877
List * lappend(List *list, void *datum)
Definition: list.c:128
static uint32 speculativeInsertionToken
Definition: lmgr.c:43
#define VirtualTransactionIdIsValid(vxid)
Definition: lock.h:71
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:513
Oid MyDatabaseId
Definition: globals.c:77
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:220
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:897
void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
Definition: lmgr.c:837
#define InvalidOid
Definition: postgres_ext.h:36
bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:275
#define SET_LOCKTAG_PAGE(locktag, dboid, reloid, blocknum)
Definition: lock.h:209
#define LOCKTAG_LAST_TYPE
Definition: lock.h:166
uint8 locktag_type
Definition: lock.h:184
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:554
const char * GetLockNameFromTagType(uint16 locktag_type)
Definition: lmgr.c:1065
#define Assert(condition)
Definition: c.h:688
#define lfirst(lc)
Definition: pg_list.h:106
Definition: lmgr.h:29
#define SET_LOCKTAG_TRANSACTION(locktag, xid)
Definition: lock.h:225
void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:455
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:492
static int list_length(const List *l)
Definition: pg_list.h:89
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:95
void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:435
int LockWaiterCount(const LOCKTAG *locktag)
Definition: lock.c:4387
bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
Definition: lmgr.c:419
XLTW_Oper
Definition: lmgr.h:24
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
Definition: lock.c:2745
#define SET_LOCKTAG_OBJECT(locktag, dboid, classoid, objoid, objsubid)
Definition: lock.h:249
LockAcquireResult
Definition: lock.h:471
void list_free(List *list)
Definition: list.c:1133
#define ShareLock
Definition: lockdefs.h:41
void LockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:199
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1818
#define errcontext
Definition: elog.h:164
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:571
void * arg
const char *const LockTagTypeNames[]
Definition: lockfuncs.c:26
LockTagType
Definition: lock.h:138
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:530
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:76
struct XactLockTableWaitInfo XactLockTableWaitInfo
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
uint32 locktag_field1
Definition: lock.h:180
Definition: pg_list.h:45
#define SET_LOCKTAG_RELATION_EXTEND(locktag, dboid, reloid)
Definition: lock.h:201
#define _(x)
Definition: elog.c:84
void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
Definition: lmgr.c:793
#define RelationGetRelid(relation)
Definition: rel.h:425
uint32 locktag_field3
Definition: lock.h:182
Oid relId
Definition: rel.h:38