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