PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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 
561  /*
562  * If an operation is specified, set up our verbose error context
563  * callback.
564  */
565  if (oper != XLTW_None)
566  {
567  Assert(RelationIsValid(rel));
568  Assert(ItemPointerIsValid(ctid));
569 
570  info.rel = rel;
571  info.ctid = ctid;
572  info.oper = oper;
573 
575  callback.arg = &info;
576  callback.previous = error_context_stack;
578  }
579 
580  for (;;)
581  {
584 
585  SET_LOCKTAG_TRANSACTION(tag, xid);
586 
587  (void) LockAcquire(&tag, ShareLock, false, false);
588 
589  LockRelease(&tag, ShareLock, false);
590 
591  if (!TransactionIdIsInProgress(xid))
592  break;
593  xid = SubTransGetParent(xid);
594  }
595 
596  if (oper != XLTW_None)
597  error_context_stack = callback.previous;
598 }
599 
600 /*
601  * ConditionalXactLockTableWait
602  *
603  * As above, but only lock if we can get the lock without blocking.
604  * Returns TRUE if the lock was acquired.
605  */
606 bool
608 {
609  LOCKTAG tag;
610 
611  for (;;)
612  {
615 
616  SET_LOCKTAG_TRANSACTION(tag, xid);
617 
618  if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
619  return false;
620 
621  LockRelease(&tag, ShareLock, false);
622 
623  if (!TransactionIdIsInProgress(xid))
624  break;
625  xid = SubTransGetParent(xid);
626  }
627 
628  return true;
629 }
630 
631 /*
632  * SpeculativeInsertionLockAcquire
633  *
634  * Insert a lock showing that the given transaction ID is inserting a tuple,
635  * but hasn't yet decided whether it's going to keep it. The lock can then be
636  * used to wait for the decision to go ahead with the insertion, or aborting
637  * it.
638  *
639  * The token is used to distinguish multiple insertions by the same
640  * transaction. It is returned to caller.
641  */
642 uint32
644 {
645  LOCKTAG tag;
646 
648 
649  /*
650  * Check for wrap-around. Zero means no token is held, so don't use that.
651  */
652  if (speculativeInsertionToken == 0)
654 
656 
657  (void) LockAcquire(&tag, ExclusiveLock, false, false);
658 
660 }
661 
662 /*
663  * SpeculativeInsertionLockRelease
664  *
665  * Delete the lock showing that the given transaction is speculatively
666  * inserting a tuple.
667  */
668 void
670 {
671  LOCKTAG tag;
672 
674 
675  LockRelease(&tag, ExclusiveLock, false);
676 }
677 
678 /*
679  * SpeculativeInsertionWait
680  *
681  * Wait for the specified transaction to finish or abort the insertion of a
682  * tuple.
683  */
684 void
686 {
687  LOCKTAG tag;
688 
689  SET_LOCKTAG_SPECULATIVE_INSERTION(tag, xid, token);
690 
692  Assert(token != 0);
693 
694  (void) LockAcquire(&tag, ShareLock, false, false);
695  LockRelease(&tag, ShareLock, false);
696 }
697 
698 /*
699  * XactLockTableWaitErrorContextCb
700  * Error context callback for transaction lock waits.
701  */
702 static void
704 {
706 
707  /*
708  * We would like to print schema name too, but that would require a
709  * syscache lookup.
710  */
711  if (info->oper != XLTW_None &&
712  ItemPointerIsValid(info->ctid) && RelationIsValid(info->rel))
713  {
714  const char *cxt;
715 
716  switch (info->oper)
717  {
718  case XLTW_Update:
719  cxt = gettext_noop("while updating tuple (%u,%u) in relation \"%s\"");
720  break;
721  case XLTW_Delete:
722  cxt = gettext_noop("while deleting tuple (%u,%u) in relation \"%s\"");
723  break;
724  case XLTW_Lock:
725  cxt = gettext_noop("while locking tuple (%u,%u) in relation \"%s\"");
726  break;
727  case XLTW_LockUpdated:
728  cxt = gettext_noop("while locking updated version (%u,%u) of tuple in relation \"%s\"");
729  break;
730  case XLTW_InsertIndex:
731  cxt = gettext_noop("while inserting index tuple (%u,%u) in relation \"%s\"");
732  break;
734  cxt = gettext_noop("while checking uniqueness of tuple (%u,%u) in relation \"%s\"");
735  break;
736  case XLTW_FetchUpdated:
737  cxt = gettext_noop("while rechecking updated tuple (%u,%u) in relation \"%s\"");
738  break;
740  cxt = gettext_noop("while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"");
741  break;
742 
743  default:
744  return;
745  }
746 
747  errcontext(cxt,
751  }
752 }
753 
754 /*
755  * WaitForLockersMultiple
756  * Wait until no transaction holds locks that conflict with the given
757  * locktags at the given lockmode.
758  *
759  * To do this, obtain the current list of lockers, and wait on their VXIDs
760  * until they are finished.
761  *
762  * Note we don't try to acquire the locks on the given locktags, only the VXIDs
763  * of its lock holders; if somebody grabs a conflicting lock on the objects
764  * after we obtained our initial list of lockers, we will not wait for them.
765  */
766 void
768 {
769  List *holders = NIL;
770  ListCell *lc;
771 
772  /* Done if no locks to wait for */
773  if (list_length(locktags) == 0)
774  return;
775 
776  /* Collect the transactions we need to wait on */
777  foreach(lc, locktags)
778  {
779  LOCKTAG *locktag = lfirst(lc);
780 
781  holders = lappend(holders, GetLockConflicts(locktag, lockmode));
782  }
783 
784  /*
785  * Note: GetLockConflicts() never reports our own xid, hence we need not
786  * check for that. Also, prepared xacts are not reported, which is fine
787  * since they certainly aren't going to do anything anymore.
788  */
789 
790  /* Finally wait for each such transaction to complete */
791  foreach(lc, holders)
792  {
793  VirtualTransactionId *lockholders = lfirst(lc);
794 
795  while (VirtualTransactionIdIsValid(*lockholders))
796  {
797  VirtualXactLock(*lockholders, true);
798  lockholders++;
799  }
800  }
801 
802  list_free_deep(holders);
803 }
804 
805 /*
806  * WaitForLockers
807  *
808  * Same as WaitForLockersMultiple, for a single lock tag.
809  */
810 void
811 WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
812 {
813  List *l;
814 
815  l = list_make1(&heaplocktag);
816  WaitForLockersMultiple(l, lockmode);
817  list_free(l);
818 }
819 
820 
821 /*
822  * LockDatabaseObject
823  *
824  * Obtain a lock on a general object of the current database. Don't use
825  * this for shared objects (such as tablespaces). It's unwise to apply it
826  * to relations, also, since a lock taken this way will NOT conflict with
827  * locks taken via LockRelation and friends.
828  */
829 void
830 LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
831  LOCKMODE lockmode)
832 {
833  LOCKTAG tag;
834 
835  SET_LOCKTAG_OBJECT(tag,
836  MyDatabaseId,
837  classid,
838  objid,
839  objsubid);
840 
841  (void) LockAcquire(&tag, lockmode, false, false);
842 
843  /* Make sure syscaches are up-to-date with any changes we waited for */
845 }
846 
847 /*
848  * UnlockDatabaseObject
849  */
850 void
851 UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
852  LOCKMODE lockmode)
853 {
854  LOCKTAG tag;
855 
856  SET_LOCKTAG_OBJECT(tag,
857  MyDatabaseId,
858  classid,
859  objid,
860  objsubid);
861 
862  LockRelease(&tag, lockmode, false);
863 }
864 
865 /*
866  * LockSharedObject
867  *
868  * Obtain a lock on a shared-across-databases object.
869  */
870 void
871 LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
872  LOCKMODE lockmode)
873 {
874  LOCKTAG tag;
875 
876  SET_LOCKTAG_OBJECT(tag,
877  InvalidOid,
878  classid,
879  objid,
880  objsubid);
881 
882  (void) LockAcquire(&tag, lockmode, false, false);
883 
884  /* Make sure syscaches are up-to-date with any changes we waited for */
886 }
887 
888 /*
889  * UnlockSharedObject
890  */
891 void
892 UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
893  LOCKMODE lockmode)
894 {
895  LOCKTAG tag;
896 
897  SET_LOCKTAG_OBJECT(tag,
898  InvalidOid,
899  classid,
900  objid,
901  objsubid);
902 
903  LockRelease(&tag, lockmode, false);
904 }
905 
906 /*
907  * LockSharedObjectForSession
908  *
909  * Obtain a session-level lock on a shared-across-databases object.
910  * See LockRelationIdForSession for notes about session-level locks.
911  */
912 void
913 LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
914  LOCKMODE lockmode)
915 {
916  LOCKTAG tag;
917 
918  SET_LOCKTAG_OBJECT(tag,
919  InvalidOid,
920  classid,
921  objid,
922  objsubid);
923 
924  (void) LockAcquire(&tag, lockmode, true, false);
925 }
926 
927 /*
928  * UnlockSharedObjectForSession
929  */
930 void
931 UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
932  LOCKMODE lockmode)
933 {
934  LOCKTAG tag;
935 
936  SET_LOCKTAG_OBJECT(tag,
937  InvalidOid,
938  classid,
939  objid,
940  objsubid);
941 
942  LockRelease(&tag, lockmode, true);
943 }
944 
945 
946 /*
947  * Append a description of a lockable object to buf.
948  *
949  * Ideally we would print names for the numeric values, but that requires
950  * getting locks on system tables, which might cause problems since this is
951  * typically used to report deadlock situations.
952  */
953 void
955 {
956  switch ((LockTagType) tag->locktag_type)
957  {
958  case LOCKTAG_RELATION:
959  appendStringInfo(buf,
960  _("relation %u of database %u"),
961  tag->locktag_field2,
962  tag->locktag_field1);
963  break;
965  appendStringInfo(buf,
966  _("extension of relation %u of database %u"),
967  tag->locktag_field2,
968  tag->locktag_field1);
969  break;
970  case LOCKTAG_PAGE:
971  appendStringInfo(buf,
972  _("page %u of relation %u of database %u"),
973  tag->locktag_field3,
974  tag->locktag_field2,
975  tag->locktag_field1);
976  break;
977  case LOCKTAG_TUPLE:
978  appendStringInfo(buf,
979  _("tuple (%u,%u) of relation %u of database %u"),
980  tag->locktag_field3,
981  tag->locktag_field4,
982  tag->locktag_field2,
983  tag->locktag_field1);
984  break;
985  case LOCKTAG_TRANSACTION:
986  appendStringInfo(buf,
987  _("transaction %u"),
988  tag->locktag_field1);
989  break;
991  appendStringInfo(buf,
992  _("virtual transaction %d/%u"),
993  tag->locktag_field1,
994  tag->locktag_field2);
995  break;
997  appendStringInfo(buf,
998  _("speculative token %u of transaction %u"),
999  tag->locktag_field2,
1000  tag->locktag_field1);
1001  break;
1002  case LOCKTAG_OBJECT:
1003  appendStringInfo(buf,
1004  _("object %u of class %u of database %u"),
1005  tag->locktag_field3,
1006  tag->locktag_field2,
1007  tag->locktag_field1);
1008  break;
1009  case LOCKTAG_USERLOCK:
1010  /* reserved for old contrib code, now on pgfoundry */
1011  appendStringInfo(buf,
1012  _("user lock [%u,%u,%u]"),
1013  tag->locktag_field1,
1014  tag->locktag_field2,
1015  tag->locktag_field3);
1016  break;
1017  case LOCKTAG_ADVISORY:
1018  appendStringInfo(buf,
1019  _("advisory lock [%u,%u,%u,%u]"),
1020  tag->locktag_field1,
1021  tag->locktag_field2,
1022  tag->locktag_field3,
1023  tag->locktag_field4);
1024  break;
1025  default:
1026  appendStringInfo(buf,
1027  _("unrecognized locktag type %d"),
1028  (int) tag->locktag_type);
1029  break;
1030  }
1031 }
1032 
1033 /*
1034  * GetLockNameFromTagType
1035  *
1036  * Given locktag type, return the corresponding lock name.
1037  */
1038 const char *
1040 {
1041  if (locktag_type > LOCKTAG_LAST_TYPE)
1042  return "???";
1043  return LockTagTypeNames[locktag_type];
1044 }
#define SET_LOCKTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
Definition: lock.h:218
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
#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:669
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:683
void AcceptInvalidationMessages(void)
Definition: inval.c:672
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
uint32 TransactionId
Definition: c.h:394
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
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
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:106
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
Oid dbId
Definition: rel.h:39
Definition: lock.h:179
#define gettext_noop(x)
Definition: c.h:139
uint32 SpeculativeInsertionLockAcquire(TransactionId xid)
Definition: lmgr.c:643
uint32 BlockNumber
Definition: block.h:31
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
struct ErrorContextCallback * previous
Definition: elog.h:238
#define OidIsValid(objectId)
Definition: c.h:534
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:607
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:913
uint16 locktag_field4
Definition: lock.h:184
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:133
unsigned short uint16
Definition: c.h:264
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
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:892
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:299
#define RelationIsValid(relation)
Definition: rel.h:386
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:49
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition: lmgr.c:954
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:685
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:931
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:194
LockInfoData rd_lockInfo
Definition: rel.h:116
static char * buf
Definition: pg_test_fsync.c:65
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:830
uint32 locktag_field2
Definition: lock.h:182
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:226
#define RelationGetRelationName(relation)
Definition: rel.h:433
unsigned int uint32
Definition: c.h:265
ItemPointer ctid
Definition: lmgr.c:56
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:403
#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag, xid, token)
Definition: lock.h:242
static void XactLockTableWaitErrorCb(void *arg)
Definition: lmgr.c:703
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:851
List * lappend(List *list, void *datum)
Definition: list.c:128
static uint32 speculativeInsertionToken
Definition: lmgr.c:43
#define VirtualTransactionIdIsValid(vxid)
Definition: lock.h:72
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:76
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:219
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:871
void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
Definition: lmgr.c:811
#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:210
#define LOCKTAG_LAST_TYPE
Definition: lock.h:167
uint8 locktag_type
Definition: lock.h:185
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:554
const char * GetLockNameFromTagType(uint16 locktag_type)
Definition: lmgr.c:1039
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
Definition: lmgr.h:29
#define SET_LOCKTAG_TRANSACTION(locktag, xid)
Definition: lock.h:226
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:76
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:250
void(* callback)(void *arg)
Definition: elog.h:239
LockAcquireResult
Definition: lock.h:472
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:139
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:530
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
struct XactLockTableWaitInfo XactLockTableWaitInfo
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:375
uint32 locktag_field1
Definition: lock.h:181
Definition: pg_list.h:45
#define SET_LOCKTAG_RELATION_EXTEND(locktag, dboid, reloid)
Definition: lock.h:202
#define _(x)
Definition: elog.c:84
void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
Definition: lmgr.c:767
#define RelationGetRelid(relation)
Definition: rel.h:413
uint32 locktag_field3
Definition: lock.h:183
Oid relId
Definition: rel.h:38