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