PostgreSQL Source Code git master
Loading...
Searching...
No Matches
proc.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * proc.c
4 * routines to manage per-process shared memory data structure
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/storage/lmgr/proc.c
12 *
13 *-------------------------------------------------------------------------
14 */
15/*
16 * Interface (a):
17 * JoinWaitQueue(), ProcSleep(), ProcWakeup()
18 *
19 * Waiting for a lock causes the backend to be put to sleep. Whoever releases
20 * the lock wakes the process up again (and gives it an error code so it knows
21 * whether it was awoken on an error condition).
22 *
23 * Interface (b):
24 *
25 * ProcReleaseLocks -- frees the locks associated with current transaction
26 *
27 * ProcKill -- destroys the shared memory state (and locks)
28 * associated with the process.
29 */
30#include "postgres.h"
31
32#include <signal.h>
33#include <unistd.h>
34#include <sys/time.h>
35
36#include "access/clog.h"
37#include "access/transam.h"
38#include "access/twophase.h"
39#include "access/xlogutils.h"
40#include "access/xlogwait.h"
41#include "miscadmin.h"
42#include "pgstat.h"
45#include "replication/syncrep.h"
47#include "storage/ipc.h"
48#include "storage/lmgr.h"
49#include "storage/pmsignal.h"
50#include "storage/proc.h"
51#include "storage/procarray.h"
52#include "storage/procsignal.h"
53#include "storage/spin.h"
54#include "storage/standby.h"
55#include "storage/subsystems.h"
57#include "utils/timeout.h"
58#include "utils/timestamp.h"
59#include "utils/wait_event.h"
60
61/* GUC variables */
62int DeadlockTimeout = 1000;
68bool log_lock_waits = true;
69
70/* Pointer to this process's PGPROC struct, if any */
72
73/* Pointers to shared-memory structures */
75static void *AllProcsShmemPtr;
79
80static void ProcGlobalShmemRequest(void *arg);
81static void ProcGlobalShmemInit(void *arg);
82
87
91
92/* Is a deadlock check pending? */
94
95static void RemoveProcFromArray(int code, Datum arg);
96static void ProcKill(int code, Datum arg);
97static void AuxiliaryProcKill(int code, Datum arg);
98static DeadLockState CheckDeadLock(void);
99
100
101/*
102 * Calculate shared-memory space needed by Fast-Path locks.
103 */
104static Size
106{
107 Size size = 0;
110
111 /*
112 * Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
113 * nicely aligned in each backend.
114 */
117
119
120 Assert(TotalProcs > 0);
121 Assert(size > 0);
122
123 return size;
124}
125
126/*
127 * Report number of semaphores needed by ProcGlobalShmemInit.
128 */
129int
131{
132 /*
133 * We need a sema per backend (including autovacuum), plus one for each
134 * auxiliary process.
135 */
137}
138
139/*
140 * ProcGlobalShmemRequest
141 * Register shared memory needs.
142 *
143 * This is called during postmaster or standalone backend startup, and also
144 * during backend startup in EXEC_BACKEND mode.
145 */
146static void
148{
149 Size size;
150
151 /*
152 * Reserve all the PGPROC structures we'll need. There are six separate
153 * consumers: (1) normal backends, (2) autovacuum workers and special
154 * workers, (3) background workers, (4) walsenders, (5) auxiliary
155 * processes, and (6) prepared transactions. (For largely-historical
156 * reasons, we combine autovacuum and special workers into one category
157 * with a single freelist.) Each PGPROC structure is dedicated to exactly
158 * one of these purposes, and they do not move between groups.
159 */
160 TotalProcs =
162
163 size = 0;
164 size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
165 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
166 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
167 size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
169 ShmemRequestStruct(.name = "PGPROC structures",
171 .ptr = &AllProcsShmemPtr,
172 );
173
176 else
178 ShmemRequestStruct(.name = "Fast-Path Lock Array",
179 .size = size,
181 );
182
183 /*
184 * ProcGlobal is registered here in .ptr as usual, but it needs to be
185 * propagated specially in EXEC_BACKEND mode, because ProcGlobal needs to
186 * be accessed early at backend startup, before ShmemAttachRequested() has
187 * been called.
188 */
189 ShmemRequestStruct(.name = "Proc Header",
190 .size = sizeof(PROC_HDR),
191 .ptr = (void **) &ProcGlobal,
192 );
193
194 /* Let the semaphore implementation register its shared memory needs */
196}
197
198
199/*
200 * ProcGlobalShmemInit -
201 * Initialize the global process table during postmaster or standalone
202 * backend startup.
203 *
204 * We also create all the per-process semaphores we will need to support
205 * the requested number of backends. We used to allocate semaphores
206 * only when backends were actually started up, but that is bad because
207 * it lets Postgres fail under load --- a lot of Unix systems are
208 * (mis)configured with small limits on the number of semaphores, and
209 * running out when trying to start another backend is a common failure.
210 * So, now we grab enough semaphores to support the desired max number
211 * of backends immediately at initialization --- if the sysadmin has set
212 * MaxConnections, max_worker_processes, max_wal_senders, or
213 * autovacuum_worker_slots higher than his kernel will support, he'll
214 * find out sooner rather than later.
215 *
216 * Another reason for creating semaphores here is that the semaphore
217 * implementation typically requires us to create semaphores in the
218 * postmaster, not in backends.
219 */
220static void
222{
223 char *ptr;
224 size_t requestSize;
225 PGPROC *procs;
226 int i,
227 j;
228
229 /* Used for setup of per-backend fast-path slots. */
230 char *fpPtr,
234
248
249 ptr = AllProcsShmemPtr;
251 MemSet(ptr, 0, requestSize);
252
253 /* Carve out the allProcs array from the shared memory area */
254 procs = (PGPROC *) ptr;
255 ptr = ptr + TotalProcs * sizeof(PGPROC);
256
257 ProcGlobal->allProcs = procs;
258 /* XXX allProcCount isn't really all of them; it excludes prepared xacts */
260
261 /*
262 * Carve out arrays mirroring PGPROC fields in a dense manner. See
263 * PROC_HDR.
264 *
265 * XXX: It might make sense to increase padding for these arrays, given
266 * how hotly they are accessed.
267 */
268 ProcGlobal->xids = (TransactionId *) ptr;
269 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->xids));
270
272 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates));
273
274 ProcGlobal->statusFlags = (uint8 *) ptr;
275 ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
276
277 /* make sure we didn't overflow */
278 Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
279
280 /*
281 * Initialize arrays for fast-path locks. Those are variable-length, so
282 * can't be included in PGPROC directly. We allocate a separate piece of
283 * shared memory and then divide that between backends.
284 */
287
291
292 /* For asserts checking we did not overflow. */
294
295 /* Initialize semaphores */
297
298 for (i = 0; i < TotalProcs; i++)
299 {
300 PGPROC *proc = &procs[i];
301
302 /* Common initialization for all PGPROCs, regardless of type. */
303
304 /*
305 * Set the fast-path lock arrays, and move the pointer. We interleave
306 * the two arrays, to (hopefully) get some locality for each backend.
307 */
308 proc->fpLockBits = (uint64 *) fpPtr;
310
311 proc->fpRelId = (Oid *) fpPtr;
313
315
316 /*
317 * Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
318 * dummy PGPROCs don't need these though - they're never associated
319 * with a real process
320 */
322 {
323 proc->sem = PGSemaphoreCreate();
324 InitSharedLatch(&(proc->procLatch));
326 }
327
328 /*
329 * Newly created PGPROCs for normal backends, autovacuum workers,
330 * special workers, bgworkers, and walsenders must be queued up on the
331 * appropriate free list. Because there can only ever be a small,
332 * fixed number of auxiliary processes, no free list is used in that
333 * case; InitAuxiliaryProcess() instead uses a linear search. PGPROCs
334 * for prepared transactions are added to a free list by
335 * TwoPhaseShmemInit().
336 */
337 if (i < MaxConnections)
338 {
339 /* PGPROC for normal backend, add to freeProcs list */
342 }
344 {
345 /* PGPROC for AV or special worker, add to autovacFreeProcs list */
348 }
350 {
351 /* PGPROC for bgworker, add to bgworkerFreeProcs list */
354 }
355 else if (i < MaxBackends)
356 {
357 /* PGPROC for walsender, add to walsenderFreeProcs list */
360 }
361
362 /* Initialize myProcLocks[] shared memory queues. */
363 for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
364 dlist_init(&(proc->myProcLocks[j]));
365
366 /* Initialize lockGroupMembers list. */
368
369 /*
370 * Initialize the atomic variables, otherwise, it won't be safe to
371 * access them for backends that aren't currently in use.
372 */
375 pg_atomic_init_u64(&(proc->waitStart), 0);
376 }
377
378 /* Should have consumed exactly the expected amount of fast-path memory. */
380
381 /*
382 * Save pointers to the blocks of PGPROC structures reserved for auxiliary
383 * processes and prepared transactions.
384 */
385 AuxiliaryProcs = &procs[MaxBackends];
387}
388
389/*
390 * InitProcess -- initialize a per-process PGPROC entry for this backend
391 */
392void
394{
395 dlist_head *procgloballist;
396
397 /*
398 * ProcGlobal should be set up already (if we are a backend, we inherit
399 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
400 */
401 if (ProcGlobal == NULL)
402 elog(PANIC, "proc header uninitialized");
403
404 if (MyProc != NULL)
405 elog(ERROR, "you already exist");
406
407 /*
408 * Before we start accessing the shared memory in a serious way, mark
409 * ourselves as an active postmaster child; this is so that the postmaster
410 * can detect it if we exit without cleaning up.
411 */
414
415 /*
416 * Decide which list should supply our PGPROC. This logic must match the
417 * way the freelists were constructed in ProcGlobalShmemInit().
418 */
420 procgloballist = &ProcGlobal->autovacFreeProcs;
421 else if (AmBackgroundWorkerProcess())
422 procgloballist = &ProcGlobal->bgworkerFreeProcs;
423 else if (AmWalSenderProcess())
424 procgloballist = &ProcGlobal->walsenderFreeProcs;
425 else
426 procgloballist = &ProcGlobal->freeProcs;
427
428 /*
429 * Try to get a proc struct from the appropriate free list. If this
430 * fails, we must be out of PGPROC structures (not to mention semaphores).
431 *
432 * While we are holding the spinlock, also copy the current shared
433 * estimate of spins_per_delay to local storage.
434 */
436
438
439 if (!dlist_is_empty(procgloballist))
440 {
441 MyProc = dlist_container(PGPROC, freeProcsLink, dlist_pop_head_node(procgloballist));
443 }
444 else
445 {
446 /*
447 * If we reach here, all the PGPROCs are in use. This is one of the
448 * possible places to detect "too many backends", so give the standard
449 * error message. XXX do we need to give a different failure message
450 * in the autovacuum case?
451 */
453 if (AmWalSenderProcess())
456 errmsg("number of requested standby connections exceeds \"max_wal_senders\" (currently %d)",
460 errmsg("sorry, too many clients already")));
461 }
463
464 /*
465 * Cross-check that the PGPROC is of the type we expect; if this were not
466 * the case, it would get returned to the wrong list.
467 */
468 Assert(MyProc->procgloballist == procgloballist);
469
470 /*
471 * Initialize all fields of MyProc, except for those previously
472 * initialized by ProcGlobalShmemInit.
473 */
476 MyProc->fpVXIDLock = false;
483 /* databaseId and roleId will be filled in later */
489 MyProc->statusFlags = 0;
490 /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
494 MyProc->lwWaitMode = 0;
499#ifdef USE_ASSERT_CHECKING
500 {
501 int i;
502
503 /* Last process should have released all locks. */
504 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
506 }
507#endif
509
510 /* Initialize fields for sync rep */
514
515 /* Initialize fields for group XID clearing. */
519
520 /* Check that group locking fields are in a proper initial state. */
523
524 /* Initialize wait event information. */
526
527 /* Initialize fields for group transaction status update. */
528 MyProc->clogGroupMember = false;
534
535 /*
536 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
537 * on it. That allows us to repoint the process latch, which so far
538 * points to process local one, to the shared one.
539 */
542
543 /* now that we have a proc, report wait events to shared memory */
545
546 /*
547 * We might be reusing a semaphore that belonged to a failed process. So
548 * be careful and reinitialize its value here. (This is not strictly
549 * necessary anymore, but seems like a good idea for cleanliness.)
550 */
552
553 /* autovacuum launcher is specially advertised in ProcGlobal */
556
557 /*
558 * Arrange to clean up at backend exit.
559 */
561
562 /*
563 * Now that we have a PGPROC, we could try to acquire locks, so initialize
564 * local state needed for LWLocks, and the deadlock checker.
565 */
568
569#ifdef EXEC_BACKEND
570
571 /*
572 * Initialize backend-local pointers to all the shared data structures.
573 * (We couldn't do this until now because it needs LWLocks.)
574 */
577#endif
578}
579
580/*
581 * InitProcessPhase2 -- make MyProc visible in the shared ProcArray.
582 *
583 * This is separate from InitProcess because we can't acquire LWLocks until
584 * we've created a PGPROC, but in the EXEC_BACKEND case ProcArrayAdd won't
585 * work until after we've done AttachSharedMemoryStructs.
586 */
587void
589{
590 Assert(MyProc != NULL);
591
592 /*
593 * Add our PGPROC to the PGPROC array in shared memory.
594 */
596
597 /*
598 * Arrange to clean that up at backend exit.
599 */
601}
602
603/*
604 * InitAuxiliaryProcess -- create a PGPROC entry for an auxiliary process
605 *
606 * This is called by bgwriter and similar processes so that they will have a
607 * MyProc value that's real enough to let them wait for LWLocks. The PGPROC
608 * and sema that are assigned are one of the extra ones created during
609 * ProcGlobalShmemInit.
610 *
611 * Auxiliary processes are presently not expected to wait for real (lockmgr)
612 * locks, so we need not set up the deadlock checker. They are never added
613 * to the ProcArray or the sinval messaging mechanism, either. They also
614 * don't get a VXID assigned, since this is only useful when we actually
615 * hold lockmgr locks.
616 *
617 * Startup process however uses locks but never waits for them in the
618 * normal backend sense. Startup process also takes part in sinval messaging
619 * as a sendOnly process, so never reads messages from sinval queue. So
620 * Startup process does have a VXID and does show up in pg_locks.
621 */
622void
624{
626 int proctype;
627
628 /*
629 * ProcGlobal should be set up already (if we are a backend, we inherit
630 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
631 */
632 if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
633 elog(PANIC, "proc header uninitialized");
634
635 if (MyProc != NULL)
636 elog(ERROR, "you already exist");
637
640
641 /*
642 * We use the freeProcsLock to protect assignment and releasing of
643 * AuxiliaryProcs entries.
644 *
645 * While we are holding the spinlock, also copy the current shared
646 * estimate of spins_per_delay to local storage.
647 */
649
651
652 /*
653 * Find a free auxproc ... *big* trouble if there isn't one ...
654 */
656 {
658 if (auxproc->pid == 0)
659 break;
660 }
662 {
664 elog(FATAL, "all AuxiliaryProcs are in use");
665 }
666
667 /* Mark auxiliary proc as in use by me */
668 auxproc->pid = MyProcPid;
669
671
672 MyProc = auxproc;
674
675 /*
676 * Initialize all fields of MyProc, except for those previously
677 * initialized by ProcGlobalShmemInit.
678 */
681 MyProc->fpVXIDLock = false;
692 MyProc->statusFlags = 0;
694 MyProc->lwWaitMode = 0;
699#ifdef USE_ASSERT_CHECKING
700 {
701 int i;
702
703 /* Last process should have released all locks. */
704 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
706 }
707#endif
709
710 /*
711 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch
712 * on it. That allows us to repoint the process latch, which so far
713 * points to process local one, to the shared one.
714 */
717
718 /* now that we have a proc, report wait events to shared memory */
720
721 /* Check that group locking fields are in a proper initial state. */
724
725 /*
726 * We might be reusing a semaphore that belonged to a failed process. So
727 * be careful and reinitialize its value here. (This is not strictly
728 * necessary anymore, but seems like a good idea for cleanliness.)
729 */
731
732 /* Some aux processes are also advertised in ProcGlobal */
737
738 /*
739 * Arrange to clean up at process exit.
740 */
742
743 /*
744 * Now that we have a PGPROC, we could try to acquire lightweight locks.
745 * Initialize local state needed for them. (Heavyweight locks cannot be
746 * acquired in aux processes.)
747 */
749
750#ifdef EXEC_BACKEND
751
752 /*
753 * Initialize backend-local pointers to all the shared data structures.
754 * (We couldn't do this until now because it needs LWLocks.)
755 */
758#endif
759}
760
761/*
762 * Used from bufmgr to share the value of the buffer that Startup waits on,
763 * or to reset the value to "not waiting" (-1). This allows processing
764 * of recovery conflicts for buffer pins. Set is made before backends look
765 * at this value, so locking not required, especially since the set is
766 * an atomic integer set operation.
767 */
768void
770{
771 /* use volatile pointer to prevent code rearrangement */
772 volatile PROC_HDR *procglobal = ProcGlobal;
773
775}
776
777/*
778 * Used by backends when they receive a request to check for buffer pin waits.
779 */
780int
782{
783 /* use volatile pointer to prevent code rearrangement */
784 volatile PROC_HDR *procglobal = ProcGlobal;
785
787}
788
789/*
790 * Check whether there are at least N free PGPROC objects. If false is
791 * returned, *nfree will be set to the number of free PGPROC objects.
792 * Otherwise, *nfree will be set to n.
793 *
794 * Note: this is designed on the assumption that N will generally be small.
795 */
796bool
797HaveNFreeProcs(int n, int *nfree)
798{
799 dlist_iter iter;
800
801 Assert(n > 0);
802 Assert(nfree);
803
805
806 *nfree = 0;
808 {
809 (*nfree)++;
810 if (*nfree == n)
811 break;
812 }
813
815
816 return (*nfree == n);
817}
818
819/*
820 * Cancel any pending wait for lock, when aborting a transaction, and revert
821 * any strong lock count acquisition for a lock being acquired.
822 *
823 * (Normally, this would only happen if we accept a cancel/die
824 * interrupt while waiting; but an ereport(ERROR) before or during the lock
825 * wait is within the realm of possibility, too.)
826 */
827void
829{
833
835
837
838 /* Nothing to do if we weren't waiting for a lock */
840 if (lockAwaited == NULL)
841 {
843 return;
844 }
845
846 /*
847 * Turn off the deadlock and lock timeout timers, if they are still
848 * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT
849 * indicator flag, since this function is executed before
850 * ProcessInterrupts when responding to SIGINT; else we'd lose the
851 * knowledge that the SIGINT came from a lock timeout and not an external
852 * source.
853 */
855 timeouts[0].keep_indicator = false;
856 timeouts[1].id = LOCK_TIMEOUT;
857 timeouts[1].keep_indicator = true;
859
860 /* Unlink myself from the wait queue, if on it (might not be anymore!) */
863
865 {
866 /* We could not have been granted the lock yet */
868 }
869 else
870 {
871 /*
872 * Somebody kicked us off the lock queue already. Perhaps they
873 * granted us the lock, or perhaps they detected a deadlock. If they
874 * did grant us the lock, we'd better remember it in our local lock
875 * table.
876 */
879 }
880
882
884
886}
887
888
889/*
890 * ProcReleaseLocks() -- release locks associated with current transaction
891 * at main transaction commit or abort
892 *
893 * At main transaction commit, we release standard locks except session locks.
894 * At main transaction abort, we release all locks including session locks.
895 *
896 * Advisory locks are released only if they are transaction-level;
897 * session-level holds remain, whether this is a commit or not.
898 *
899 * At subtransaction commit, we don't release any locks (so this func is not
900 * needed at all); we will defer the releasing to the parent transaction.
901 * At subtransaction abort, we release all locks held by the subtransaction;
902 * this is implemented by retail releasing of the locks under control of
903 * the ResourceOwner mechanism.
904 */
905void
907{
908 if (!MyProc)
909 return;
910 /* If waiting, get off wait queue (should only be needed after error) */
912 /* Release standard locks, including session-level if aborting */
914 /* Release transaction-level advisory locks */
916}
917
918
919/*
920 * RemoveProcFromArray() -- Remove this process from the shared ProcArray.
921 */
922static void
928
929/*
930 * ProcKill() -- Destroy the per-proc data structure for
931 * this process. Release any of its held LW locks.
932 */
933static void
935{
936 PGPROC *proc;
937 PGPROC *leader;
938 dlist_head *procgloballist;
939 bool push_leader;
940 bool push_self;
941
942 Assert(MyProc != NULL);
943
944 /* not safe if forked by system(), etc. */
945 if (MyProc->pid != (int) getpid())
946 elog(PANIC, "ProcKill() called in child process");
947
948 /* Make sure we're out of the sync rep lists */
950
951#ifdef USE_ASSERT_CHECKING
952 {
953 int i;
954
955 /* Last process should have released all locks. */
956 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
958 }
959#endif
960
961 /*
962 * Release any LW locks I am holding. There really shouldn't be any, but
963 * it's cheap to check again before we cut the knees off the LWLock
964 * facility by releasing our PGPROC ...
965 */
967
968 /*
969 * Cleanup waiting for LSN if any.
970 */
972
973 /* Cancel any pending condition variable sleep, too */
975
976 /*
977 * Reset MyLatch to the process local one and disown the shared latch, so
978 * that signal handlers et al can continue using the latch after the
979 * shared latch isn't ours anymore.
980 *
981 * DisownLatch() must happen before our PGPROC can appear on a freelist: a
982 * newly-forked backend that pops our slot and calls OwnLatch() would
983 * PANIC on a still-owned latch.
984 *
985 * pgstat_reset_wait_event_storage() is intentionally deferred until after
986 * the lock-group block so that wait_event_info remains visible in our
987 * PGPROC slot while we may be observed there. It is safe to defer
988 * because our slot is not yet on any freelist at this point, and useful
989 * for testing purposes.
990 */
993
995 {
998 }
999
1000 proc = MyProc;
1001 procgloballist = proc->procgloballist;
1002
1003 /*
1004 * Detach from any lock group of which we are a member, deciding under
1005 * leader_lwlock whether we (via push_self) and/or the leader (via
1006 * push_leader) need to be pushed onto a freelist. The actual pushes
1007 * happen after evaluating if any of these are required, under a single
1008 * ProcGlobal->freeProcsLock.
1009 *
1010 * The decision whether any of the freelists needs to be updated is taken
1011 * under a single leader_lwlock.
1012 */
1013 push_leader = false;
1014 push_self = true;
1015 leader = NULL;
1016
1017 if (proc->lockGroupLeader != NULL)
1018 {
1020
1021 leader = proc->lockGroupLeader;
1023
1027 if (dlist_is_empty(&leader->lockGroupMembers))
1028 {
1029 leader->lockGroupLeader = NULL;
1030 if (leader != proc)
1031 {
1032 /*
1033 * We are the last follower and the leader exited earlier; its
1034 * PGPROC is still allocated and must be pushed here.
1035 */
1036 push_leader = true;
1037 proc->lockGroupLeader = NULL;
1038 }
1039 }
1040 else if (leader != proc)
1041 {
1042 /* Non-last follower; leader still present in the group. */
1043 proc->lockGroupLeader = NULL;
1044 }
1045 else
1046 {
1047 /*
1048 * We are the leader and followers remain. Skip our own push; the
1049 * last follower to exit will push us back to the freelist.
1050 */
1051 push_self = false;
1052 }
1054 }
1055
1056 /* See comment above, close to DisownLatch() */
1058
1059 MyProc = NULL;
1061
1062 /* Mark the proc no longer in use */
1063 proc->pid = 0;
1066
1068 if (push_leader)
1069 {
1070 /* Return leader PGPROC (and semaphore) to appropriate freelist */
1071 dlist_push_head(leader->procgloballist, &leader->freeProcsLink);
1072 }
1073 if (push_self)
1074 {
1075 Assert(proc->lockGroupLeader == NULL);
1076 /* Since lockGroupLeader is NULL, lockGroupMembers should be empty. */
1078
1079 /* Return PGPROC structure (and semaphore) to appropriate freelist */
1080 dlist_push_tail(procgloballist, &proc->freeProcsLink);
1081 }
1082
1083 /* Update shared estimate of spins_per_delay */
1085
1087}
1088
1089/*
1090 * AuxiliaryProcKill() -- Cut-down version of ProcKill for auxiliary
1091 * processes (bgwriter, etc). The PGPROC and sema are not released, only
1092 * marked as not-in-use.
1093 */
1094static void
1096{
1097 int proctype = DatumGetInt32(arg);
1099 PGPROC *proc;
1100
1102
1103 /* not safe if forked by system(), etc. */
1104 if (MyProc->pid != (int) getpid())
1105 elog(PANIC, "AuxiliaryProcKill() called in child process");
1106
1108
1109 Assert(MyProc == auxproc);
1110
1111 /* Release any LW locks I am holding (see notes above) */
1113
1114 /* Cancel any pending condition variable sleep, too */
1116
1117 /* look at the equivalent ProcKill() code for comments */
1120
1121 /*
1122 * If this was one of the aux processes advertised in ProcGlobal, clear it
1123 */
1125 {
1128 }
1130 {
1133 }
1134
1135 proc = MyProc;
1136 MyProc = NULL;
1138 DisownLatch(&proc->procLatch);
1139
1141
1142 /* Mark auxiliary proc no longer in use */
1143 proc->pid = 0;
1146
1147 /* Update shared estimate of spins_per_delay */
1149
1151}
1152
1153/*
1154 * AuxiliaryPidGetProc -- get PGPROC for an auxiliary process
1155 * given its PID
1156 *
1157 * Returns NULL if not found.
1158 */
1159PGPROC *
1161{
1162 PGPROC *result = NULL;
1163 int index;
1164
1165 if (pid == 0) /* never match dummy PGPROCs */
1166 return NULL;
1167
1168 for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
1169 {
1170 PGPROC *proc = &AuxiliaryProcs[index];
1171
1172 if (proc->pid == pid)
1173 {
1174 result = proc;
1175 break;
1176 }
1177 }
1178 return result;
1179}
1180
1181
1182/*
1183 * JoinWaitQueue -- join the wait queue on the specified lock
1184 *
1185 * It's not actually guaranteed that we need to wait when this function is
1186 * called, because it could be that when we try to find a position at which
1187 * to insert ourself into the wait queue, we discover that we must be inserted
1188 * ahead of everyone who wants a lock that conflict with ours. In that case,
1189 * we get the lock immediately. Because of this, it's sensible for this function
1190 * to have a dontWait argument, despite the name.
1191 *
1192 * On entry, the caller has already set up LOCK and PROCLOCK entries to
1193 * reflect that we have "requested" the lock. The caller is responsible for
1194 * cleaning that up, if we end up not joining the queue after all.
1195 *
1196 * The lock table's partition lock must be held at entry, and is still held
1197 * at exit. The caller must release it before calling ProcSleep().
1198 *
1199 * Result is one of the following:
1200 *
1201 * PROC_WAIT_STATUS_OK - lock was immediately granted
1202 * PROC_WAIT_STATUS_WAITING - joined the wait queue; call ProcSleep()
1203 * PROC_WAIT_STATUS_ERROR - immediate deadlock was detected, or would
1204 * need to wait and dontWait == true
1205 *
1206 * NOTES: The process queue is now a priority queue for locking.
1207 */
1210{
1211 LOCKMODE lockmode = locallock->tag.mode;
1212 LOCK *lock = locallock->lock;
1213 PROCLOCK *proclock = locallock->proclock;
1214 uint32 hashcode = locallock->hashcode;
1220 bool early_deadlock = false;
1221 PGPROC *leader = MyProc->lockGroupLeader;
1222
1224
1225 /*
1226 * Set bitmask of locks this process already holds on this object.
1227 */
1228 myHeldLocks = MyProc->heldLocks = proclock->holdMask;
1229
1230 /*
1231 * Determine which locks we're already holding.
1232 *
1233 * If group locking is in use, locks held by members of my locking group
1234 * need to be included in myHeldLocks. This is not required for relation
1235 * extension lock which conflict among group members. However, including
1236 * them in myHeldLocks will give group members the priority to get those
1237 * locks as compared to other backends which are also trying to acquire
1238 * those locks. OTOH, we can avoid giving priority to group members for
1239 * that kind of locks, but there doesn't appear to be a clear advantage of
1240 * the same.
1241 */
1242 myProcHeldLocks = proclock->holdMask;
1244 if (leader != NULL)
1245 {
1246 dlist_iter iter;
1247
1248 dlist_foreach(iter, &lock->procLocks)
1249 {
1251
1252 otherproclock = dlist_container(PROCLOCK, lockLink, iter.cur);
1253
1254 if (otherproclock->groupLeader == leader)
1255 myHeldLocks |= otherproclock->holdMask;
1256 }
1257 }
1258
1259 /*
1260 * Determine where to add myself in the wait queue.
1261 *
1262 * Normally I should go at the end of the queue. However, if I already
1263 * hold locks that conflict with the request of any previous waiter, put
1264 * myself in the queue just in front of the first such waiter. This is not
1265 * a necessary step, since deadlock detection would move me to before that
1266 * waiter anyway; but it's relatively cheap to detect such a conflict
1267 * immediately, and avoid delaying till deadlock timeout.
1268 *
1269 * Special case: if I find I should go in front of some waiter, check to
1270 * see if I conflict with already-held locks or the requests before that
1271 * waiter. If not, then just grant myself the requested lock immediately.
1272 * This is the same as the test for immediate grant in LockAcquire, except
1273 * we are only considering the part of the wait queue before my insertion
1274 * point.
1275 */
1277 {
1279 dlist_iter iter;
1280
1282 {
1283 PGPROC *proc = dlist_container(PGPROC, waitLink, iter.cur);
1284
1285 /*
1286 * If we're part of the same locking group as this waiter, its
1287 * locks neither conflict with ours nor contribute to
1288 * aheadRequests.
1289 */
1290 if (leader != NULL && leader == proc->lockGroupLeader)
1291 continue;
1292
1293 /* Must he wait for me? */
1294 if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
1295 {
1296 /* Must I wait for him ? */
1297 if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
1298 {
1299 /*
1300 * Yes, so we have a deadlock. Easiest way to clean up
1301 * correctly is to call RemoveFromWaitQueue(), but we
1302 * can't do that until we are *on* the wait queue. So, set
1303 * a flag to check below, and break out of loop. Also,
1304 * record deadlock info for later message.
1305 */
1306 RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
1307 early_deadlock = true;
1308 break;
1309 }
1310 /* I must go before this waiter. Check special case. */
1311 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1312 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1313 proclock))
1314 {
1315 /* Skip the wait and just grant myself the lock. */
1316 GrantLock(lock, proclock, lockmode);
1317 return PROC_WAIT_STATUS_OK;
1318 }
1319
1320 /* Put myself into wait queue before conflicting process */
1321 insert_before = proc;
1322 break;
1323 }
1324 /* Nope, so advance to next waiter */
1326 }
1327 }
1328
1329 /*
1330 * If we detected deadlock, give up without waiting. This must agree with
1331 * CheckDeadLock's recovery code.
1332 */
1333 if (early_deadlock)
1335
1336 /*
1337 * At this point we know that we'd really need to sleep. If we've been
1338 * commanded not to do that, bail out.
1339 */
1340 if (dontWait)
1342
1343 /*
1344 * Insert self into queue, at the position determined above.
1345 */
1346 if (insert_before)
1348 else
1350
1351 lock->waitMask |= LOCKBIT_ON(lockmode);
1352
1353 /* Set up wait information in PGPROC object, too */
1355 MyProc->waitLock = lock;
1356 MyProc->waitProcLock = proclock;
1357 MyProc->waitLockMode = lockmode;
1358
1360
1362}
1363
1364/*
1365 * ProcSleep -- put process to sleep waiting on lock
1366 *
1367 * This must be called when JoinWaitQueue() returns PROC_WAIT_STATUS_WAITING.
1368 * Returns after the lock has been granted, or if a deadlock is detected. Can
1369 * also bail out with ereport(ERROR), if some other error condition, or a
1370 * timeout or cancellation is triggered.
1371 *
1372 * Result is one of the following:
1373 *
1374 * PROC_WAIT_STATUS_OK - lock was granted
1375 * PROC_WAIT_STATUS_ERROR - a deadlock was detected
1376 */
1379{
1380 LOCKMODE lockmode = locallock->tag.mode;
1381 LOCK *lock = locallock->lock;
1382 uint32 hashcode = locallock->hashcode;
1385 bool allow_autovacuum_cancel = true;
1386 bool logged_recovery_conflict = false;
1387 bool logged_lock_wait = false;
1390
1391 /* The caller must've armed the on-error cleanup mechanism */
1394
1395 /*
1396 * Now that we will successfully clean up after an ereport, it's safe to
1397 * check to see if there's a buffer pin deadlock against the Startup
1398 * process. Of course, that's only necessary if we're doing Hot Standby
1399 * and are not the Startup process ourselves.
1400 */
1403
1404 /* Reset deadlock_state before enabling the timeout handler */
1406 got_deadlock_timeout = false;
1407
1408 /*
1409 * Set timer so we can wake up after awhile and check for a deadlock. If a
1410 * deadlock is detected, the handler sets MyProc->waitStatus =
1411 * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
1412 * rather than success.
1413 *
1414 * By delaying the check until we've waited for a bit, we can avoid
1415 * running the rather expensive deadlock-check code in most cases.
1416 *
1417 * If LockTimeout is set, also enable the timeout for that. We can save a
1418 * few cycles by enabling both timeout sources in one call.
1419 *
1420 * If InHotStandby we set lock waits slightly later for clarity with other
1421 * code.
1422 */
1423 if (!InHotStandby)
1424 {
1425 if (LockTimeout > 0)
1426 {
1428
1430 timeouts[0].type = TMPARAM_AFTER;
1431 timeouts[0].delay_ms = DeadlockTimeout;
1432 timeouts[1].id = LOCK_TIMEOUT;
1433 timeouts[1].type = TMPARAM_AFTER;
1434 timeouts[1].delay_ms = LockTimeout;
1436 }
1437 else
1439
1440 /*
1441 * Use the current time obtained for the deadlock timeout timer as
1442 * waitStart (i.e., the time when this process started waiting for the
1443 * lock). Since getting the current time newly can cause overhead, we
1444 * reuse the already-obtained time to avoid that overhead.
1445 *
1446 * Note that waitStart is updated without holding the lock table's
1447 * partition lock, to avoid the overhead by additional lock
1448 * acquisition. This can cause "waitstart" in pg_locks to become NULL
1449 * for a very short period of time after the wait started even though
1450 * "granted" is false. This is OK in practice because we can assume
1451 * that users are likely to look at "waitstart" when waiting for the
1452 * lock for a long time.
1453 */
1456 }
1458 {
1459 /*
1460 * Set the wait start timestamp if logging is enabled and in hot
1461 * standby.
1462 */
1464 }
1465
1466 /*
1467 * If somebody wakes us between LWLockRelease and WaitLatch, the latch
1468 * will not wait. But a set latch does not necessarily mean that the lock
1469 * is free now, as there are many other sources for latch sets than
1470 * somebody releasing the lock.
1471 *
1472 * We process interrupts whenever the latch has been set, so cancel/die
1473 * interrupts are processed quickly. This means we must not mind losing
1474 * control to a cancel/die interrupt here. We don't, because we have no
1475 * shared-state-change work to do after being granted the lock (the
1476 * grantor did it all). We do have to worry about canceling the deadlock
1477 * timeout and updating the locallock table, but if we lose control to an
1478 * error, LockErrorCleanup will fix that up.
1479 */
1480 do
1481 {
1482 if (InHotStandby)
1483 {
1484 bool maybe_log_conflict =
1486
1487 /* Set a timer and wait for that or for the lock to be granted */
1490
1491 /*
1492 * Emit the log message if the startup process is waiting longer
1493 * than deadlock_timeout for recovery conflict on lock.
1494 */
1496 {
1498
1501 {
1503 int cnt;
1504
1505 vxids = GetLockConflicts(&locallock->tag.lock,
1506 AccessExclusiveLock, &cnt);
1507
1508 /*
1509 * Log the recovery conflict and the list of PIDs of
1510 * backends holding the conflicting lock. Note that we do
1511 * logging even if there are no such backends right now
1512 * because the startup process here has already waited
1513 * longer than deadlock_timeout.
1514 */
1517 cnt > 0 ? vxids : NULL, true);
1519 }
1520 }
1521 }
1522 else
1523 {
1525 PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
1527 /* check for deadlocks first, as that's probably log-worthy */
1529 {
1531 got_deadlock_timeout = false;
1532 }
1534 }
1535
1536 /*
1537 * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
1538 * else asynchronously. Read it just once per loop to prevent
1539 * surprising behavior (such as missing log messages).
1540 */
1541 myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
1542
1543 /*
1544 * If we are not deadlocked, but are waiting on an autovacuum-induced
1545 * task, send a signal to interrupt it.
1546 */
1548 {
1550 uint8 statusFlags;
1553
1554 /*
1555 * Grab info we need, then release lock immediately. Note this
1556 * coding means that there is a tiny chance that the process
1557 * terminates its current transaction and starts a different one
1558 * before we have a change to send the signal; the worst possible
1559 * consequence is that a for-wraparound vacuum is canceled. But
1560 * that could happen in any case unless we were to do kill() with
1561 * the lock held, which is much more undesirable.
1562 */
1564 statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
1566 locktag_copy = lock->tag;
1568
1569 /*
1570 * Only do it if the worker is not working to protect against Xid
1571 * wraparound.
1572 */
1573 if ((statusFlags & PROC_IS_AUTOVACUUM) &&
1574 !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND))
1575 {
1576 int pid = autovac->pid;
1577
1578 /* report the case, if configured to do so */
1580 {
1582 StringInfoData logbuf; /* errdetail for server log */
1583
1588 "Process %d waits for %s on %s.",
1589 MyProcPid,
1591 locktagbuf.data);
1592
1594 (errmsg_internal("sending cancel to blocking autovacuum PID %d",
1595 pid),
1596 errdetail_log("%s", logbuf.data)));
1597
1598 pfree(locktagbuf.data);
1599 pfree(logbuf.data);
1600 }
1601
1602 /* send the autovacuum worker Back to Old Kent Road */
1603 if (kill(pid, SIGINT) < 0)
1604 {
1605 /*
1606 * There's a race condition here: once we release the
1607 * ProcArrayLock, it's possible for the autovac worker to
1608 * close up shop and exit before we can do the kill().
1609 * Therefore, we do not whinge about no-such-process.
1610 * Other errors such as EPERM could conceivably happen if
1611 * the kernel recycles the PID fast enough, but such cases
1612 * seem improbable enough that it's probably best to issue
1613 * a warning if we see some other errno.
1614 */
1615 if (errno != ESRCH)
1617 (errmsg("could not send signal to process %d: %m",
1618 pid)));
1619 }
1620 }
1621
1622 /* prevent signal from being sent again more than once */
1624 }
1625
1626 /*
1627 * If awoken after the deadlock check interrupt has run, increment the
1628 * lock statistics counters and if log_lock_waits is on, then report
1629 * about the wait.
1630 */
1632 {
1633 long secs;
1634 int usecs;
1635 long msecs;
1636
1637 INJECTION_POINT("deadlock-timeout-fired", NULL);
1640 &secs, &usecs);
1641 /* Increment the lock statistics counters if done waiting. */
1643 pgstat_count_lock_waits(locallock->tag.lock.locktag_type,
1644 (PgStat_Counter) secs * 1000000 + usecs);
1645
1646 msecs = secs * 1000 + usecs / 1000;
1647 usecs = usecs % 1000;
1648
1649 if (log_lock_waits)
1650 {
1654 const char *modename;
1655 int lockHoldersNum = 0;
1656
1660
1661 DescribeLockTag(&buf, &locallock->tag.lock);
1662 modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
1663 lockmode);
1664
1665 /* Gather a list of all lock holders and waiters */
1670
1672 ereport(LOG,
1673 (errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1674 MyProcPid, modename, buf.data, msecs, usecs),
1675 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1676 "Processes holding the lock: %s. Wait queue: %s.",
1678 else if (deadlock_state == DS_HARD_DEADLOCK)
1679 {
1680 /*
1681 * This message is a bit redundant with the error that
1682 * will be reported subsequently, but in some cases the
1683 * error report might not make it to the log (eg, if it's
1684 * caught by an exception handler), and we want to ensure
1685 * all long-wait events get logged.
1686 */
1687 ereport(LOG,
1688 (errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1689 MyProcPid, modename, buf.data, msecs, usecs),
1690 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1691 "Processes holding the lock: %s. Wait queue: %s.",
1693 }
1694
1696 {
1697 /*
1698 * Guard the "still waiting on lock" log message so it is
1699 * reported at most once while waiting for the lock.
1700 *
1701 * Without this guard, the message can be emitted whenever
1702 * the lock-wait sleep is interrupted (for example by
1703 * SIGHUP for config reload or by
1704 * client_connection_check_interval). For example, if
1705 * client_connection_check_interval is set very low (e.g.,
1706 * 100 ms), the message could be logged repeatedly,
1707 * flooding the log and making it difficult to use.
1708 */
1709 if (!logged_lock_wait)
1710 {
1711 ereport(LOG,
1712 (errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1713 MyProcPid, modename, buf.data, msecs, usecs),
1714 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1715 "Processes holding the lock: %s. Wait queue: %s.",
1717 logged_lock_wait = true;
1718 }
1719 }
1721 ereport(LOG,
1722 (errmsg("process %d acquired %s on %s after %ld.%03d ms",
1723 MyProcPid, modename, buf.data, msecs, usecs)));
1724 else
1725 {
1727
1728 /*
1729 * Currently, the deadlock checker always kicks its own
1730 * process, which means that we'll only see
1731 * PROC_WAIT_STATUS_ERROR when deadlock_state ==
1732 * DS_HARD_DEADLOCK, and there's no need to print
1733 * redundant messages. But for completeness and
1734 * future-proofing, print a message if it looks like
1735 * someone else kicked us off the lock.
1736 */
1738 ereport(LOG,
1739 (errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1740 MyProcPid, modename, buf.data, msecs, usecs),
1741 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1742 "Processes holding the lock: %s. Wait queue: %s.",
1744 }
1745 pfree(buf.data);
1748 }
1749
1750 /*
1751 * At this point we might still need to wait for the lock. Reset
1752 * state so we don't print the above messages again if
1753 * log_lock_waits is on.
1754 */
1756 }
1758
1759 /*
1760 * Disable the timers, if they are still running. As in LockErrorCleanup,
1761 * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has
1762 * already caused QueryCancelPending to become set, we want the cancel to
1763 * be reported as a lock timeout, not a user cancel.
1764 */
1765 if (!InHotStandby)
1766 {
1767 if (LockTimeout > 0)
1768 {
1770
1772 timeouts[0].keep_indicator = false;
1773 timeouts[1].id = LOCK_TIMEOUT;
1774 timeouts[1].keep_indicator = true;
1776 }
1777 else
1779 }
1780
1781 /*
1782 * Emit the log message if recovery conflict on lock was resolved but the
1783 * startup process waited longer than deadlock_timeout for it.
1784 */
1788 NULL, false);
1789
1790 /*
1791 * We don't have to do anything else, because the awaker did all the
1792 * necessary updates of the lock table and MyProc. (The caller is
1793 * responsible for updating the local lock table.)
1794 */
1795 return myWaitStatus;
1796}
1797
1798
1799/*
1800 * ProcWakeup -- wake up a process by setting its latch.
1801 *
1802 * Also remove the process from the wait queue and set its waitLink invalid.
1803 *
1804 * The appropriate lock partition lock must be held by caller.
1805 *
1806 * XXX: presently, this code is only used for the "success" case, and only
1807 * works correctly for that case. To clean up in failure case, would need
1808 * to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
1809 * Hence, in practice the waitStatus parameter must be PROC_WAIT_STATUS_OK.
1810 */
1811void
1813{
1814 if (dlist_node_is_detached(&proc->waitLink))
1815 return;
1816
1818
1819 /* Remove process from wait queue */
1821
1822 /* Clean up process' state and pass it the ok/fail signal */
1823 proc->waitLock = NULL;
1824 proc->waitProcLock = NULL;
1825 proc->waitStatus = waitStatus;
1826 pg_atomic_write_u64(&proc->waitStart, 0);
1827
1828 /* And awaken it */
1829 SetLatch(&proc->procLatch);
1830}
1831
1832/*
1833 * ProcLockWakeup -- routine for waking up processes when a lock is
1834 * released (or a prior waiter is aborted). Scan all waiters
1835 * for lock, waken any that are no longer blocked.
1836 *
1837 * The appropriate lock partition lock must be held by caller.
1838 */
1839void
1841{
1845
1847 return;
1848
1850 {
1851 PGPROC *proc = dlist_container(PGPROC, waitLink, miter.cur);
1852 LOCKMODE lockmode = proc->waitLockMode;
1853
1854 /*
1855 * Waken if (a) doesn't conflict with requests of earlier waiters, and
1856 * (b) doesn't conflict with already-held locks.
1857 */
1858 if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1859 !LockCheckConflicts(lockMethodTable, lockmode, lock,
1860 proc->waitProcLock))
1861 {
1862 /* OK to waken */
1863 GrantLock(lock, proc->waitProcLock, lockmode);
1864 /* removes proc from the lock's waiting process queue */
1866 }
1867 else
1868 {
1869 /*
1870 * Lock conflicts: Don't wake, but remember requested mode for
1871 * later checks.
1872 */
1873 aheadRequests |= LOCKBIT_ON(lockmode);
1874 }
1875 }
1876}
1877
1878/*
1879 * CheckDeadLock
1880 *
1881 * We only get to this routine, if DEADLOCK_TIMEOUT fired while waiting for a
1882 * lock to be released by some other process. Check if there's a deadlock; if
1883 * not, just return. If we have a real deadlock, remove ourselves from the
1884 * lock's wait queue.
1885 */
1886static DeadLockState
1888{
1889 int i;
1891
1892 /*
1893 * Acquire exclusive lock on the entire shared lock data structures. Must
1894 * grab LWLocks in partition-number order to avoid LWLock deadlock.
1895 *
1896 * Note that the deadlock check interrupt had better not be enabled
1897 * anywhere that this process itself holds lock partition locks, else this
1898 * will wait forever. Also note that LWLockAcquire creates a critical
1899 * section, so that this routine cannot be interrupted by cancel/die
1900 * interrupts.
1901 */
1902 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
1904
1905 /*
1906 * Check to see if we've been awoken by anyone in the interim.
1907 *
1908 * If we have, we can return and resume our transaction -- happy day.
1909 * Before we are awoken the process releasing the lock grants it to us so
1910 * we know that we don't have to wait anymore.
1911 *
1912 * We check by looking to see if we've been unlinked from the wait queue.
1913 * This is safe because we hold the lock partition lock.
1914 */
1916 {
1918 goto check_done;
1919 }
1920
1921#ifdef LOCK_DEBUG
1922 if (Debug_deadlocks)
1923 DumpAllLocks();
1924#endif
1925
1926 /* Run the deadlock check */
1928
1929 if (result == DS_HARD_DEADLOCK)
1930 {
1931 /*
1932 * Oops. We have a deadlock.
1933 *
1934 * Get this process out of wait state. (Note: we could do this more
1935 * efficiently by relying on lockAwaited, but use this coding to
1936 * preserve the flexibility to kill some other transaction than the
1937 * one detecting the deadlock.)
1938 *
1939 * RemoveFromWaitQueue sets MyProc->waitStatus to
1940 * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we
1941 * return.
1942 */
1945
1946 /*
1947 * We're done here. Transaction abort caused by the error that
1948 * ProcSleep will raise will cause any other locks we hold to be
1949 * released, thus allowing other processes to wake up; we don't need
1950 * to do that here. NOTE: an exception is that releasing locks we
1951 * hold doesn't consider the possibility of waiters that were blocked
1952 * behind us on the lock we just failed to get, and might now be
1953 * wakable because we're not in front of them anymore. However,
1954 * RemoveFromWaitQueue took care of waking up any such processes.
1955 */
1956 }
1957
1958 /*
1959 * And release locks. We do this in reverse order for two reasons: (1)
1960 * Anyone else who needs more than one of the locks will be trying to lock
1961 * them in increasing order; we don't want to release the other process
1962 * until it can get all the locks it needs. (2) This avoids O(N^2)
1963 * behavior inside LWLockRelease.
1964 */
1966 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1968
1969 return result;
1970}
1971
1972/*
1973 * CheckDeadLockAlert - Handle the expiry of deadlock_timeout.
1974 *
1975 * NB: Runs inside a signal handler, be careful.
1976 */
1977void
1979{
1980 int save_errno = errno;
1981
1982 got_deadlock_timeout = true;
1983
1984 /*
1985 * Have to set the latch again, even if handle_sig_alarm already did. Back
1986 * then got_deadlock_timeout wasn't yet set... It's unlikely that this
1987 * ever would be a problem, but setting a set latch again is cheap.
1988 *
1989 * Note that, when this function runs inside procsignal_sigusr1_handler(),
1990 * the handler function sets the latch again after the latch is set here.
1991 */
1993 errno = save_errno;
1994}
1995
1996/*
1997 * GetLockHoldersAndWaiters - get lock holders and waiters for a lock
1998 *
1999 * Fill lock_holders_sbuf and lock_waiters_sbuf with the PIDs of processes holding
2000 * and waiting for the lock, and set lockHoldersNum to the number of lock holders.
2001 *
2002 * The lock table's partition lock must be held on entry and remains held on exit.
2003 */
2004void
2007{
2010 LOCK *lock = locallock->lock;
2011 bool first_holder = true,
2012 first_waiter = true;
2013
2014#ifdef USE_ASSERT_CHECKING
2015 {
2016 uint32 hashcode = locallock->hashcode;
2018
2020 }
2021#endif
2022
2023 *lockHoldersNum = 0;
2024
2025 /*
2026 * Loop over the lock's procLocks to gather a list of all holders and
2027 * waiters. Thus we will be able to provide more detailed information for
2028 * lock debugging purposes.
2029 *
2030 * lock->procLocks contains all processes which hold or wait for this
2031 * lock.
2032 */
2034 {
2035 curproclock =
2036 dlist_container(PROCLOCK, lockLink, proc_iter.cur);
2037
2038 /*
2039 * We are a waiter if myProc->waitProcLock == curproclock; we are a
2040 * holder if it is NULL or something different.
2041 */
2042 if (curproclock->tag.myProc->waitProcLock == curproclock)
2043 {
2044 if (first_waiter)
2045 {
2047 curproclock->tag.myProc->pid);
2048 first_waiter = false;
2049 }
2050 else
2052 curproclock->tag.myProc->pid);
2053 }
2054 else
2055 {
2056 if (first_holder)
2057 {
2059 curproclock->tag.myProc->pid);
2060 first_holder = false;
2061 }
2062 else
2064 curproclock->tag.myProc->pid);
2065
2066 (*lockHoldersNum)++;
2067 }
2068 }
2069}
2070
2071/*
2072 * ProcWaitForSignal - wait for a signal from another backend.
2073 *
2074 * As this uses the generic process latch the caller has to be robust against
2075 * unrelated wakeups: Always check that the desired state has occurred, and
2076 * wait again if not.
2077 */
2078void
2080{
2082 wait_event_info);
2085}
2086
2087/*
2088 * ProcSendSignal - set the latch of a backend identified by ProcNumber
2089 */
2090void
2092{
2094 elog(ERROR, "procNumber out of range");
2095
2096 SetLatch(&GetPGProcByNumber(procNumber)->procLatch);
2097}
2098
2099/*
2100 * BecomeLockGroupLeader - designate process as lock group leader
2101 *
2102 * Once this function has returned, other processes can join the lock group
2103 * by calling BecomeLockGroupMember.
2104 */
2105void
2107{
2109
2110 /* If we already did it, we don't need to do it again. */
2112 return;
2113
2114 /* We had better not be a follower. */
2116
2117 /* Create single-member group, containing only ourselves. */
2123}
2124
2125/*
2126 * BecomeLockGroupMember - designate process as lock group member
2127 *
2128 * This is pretty straightforward except for the possibility that the leader
2129 * whose group we're trying to join might exit before we manage to do so;
2130 * and the PGPROC might get recycled for an unrelated process. To avoid
2131 * that, we require the caller to pass the PID of the intended PGPROC as
2132 * an interlock. Returns true if we successfully join the intended lock
2133 * group, and false if not.
2134 */
2135bool
2137{
2139 bool ok = false;
2140
2141 /* Group leader can't become member of group */
2142 Assert(MyProc != leader);
2143
2144 /* Can't already be a member of a group */
2146
2147 /* PID must be valid. */
2148 Assert(pid != 0);
2149
2150 /*
2151 * Get lock protecting the group fields. Note LockHashPartitionLockByProc
2152 * calculates the proc number based on the PGPROC slot without looking at
2153 * its contents, so we will acquire the correct lock even if the leader
2154 * PGPROC is in process of being recycled.
2155 */
2158
2159 /* Is this the leader we're looking for? */
2160 if (leader->pid == pid && leader->lockGroupLeader == leader)
2161 {
2162 /* OK, join the group */
2163 ok = true;
2164 MyProc->lockGroupLeader = leader;
2166 }
2168
2169 return ok;
2170}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:480
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition atomics.h:214
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition atomics.h:269
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition atomics.h:232
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:448
int autovacuum_worker_slots
Definition autovacuum.c:124
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1729
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1789
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
#define MAXALIGN(LEN)
Definition c.h:955
uint8_t uint8
Definition c.h:681
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:308
#define Assert(condition)
Definition c.h:1002
uint64_t uint64
Definition c.h:684
uint32_t uint32
Definition c.h:683
#define MemSet(start, val, len)
Definition c.h:1147
uint32 TransactionId
Definition c.h:795
size_t Size
Definition c.h:748
uint32 result
#define TRANSACTION_STATUS_IN_PROGRESS
Definition clog.h:27
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition timestamp.h:39
PGPROC * GetBlockingAutoVacuumPgproc(void)
Definition deadlock.c:290
void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, PGPROC *proc2)
Definition deadlock.c:1147
void InitDeadLockChecking(void)
Definition deadlock.c:143
DeadLockState DeadLockCheck(PGPROC *proc)
Definition deadlock.c:220
Datum arg
Definition elog.c:1323
bool message_level_is_interesting(int elevel)
Definition elog.c:285
int errcode(int sqlerrcode)
Definition elog.c:875
#define LOG
Definition elog.h:32
#define FATAL
Definition elog.h:42
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define PANIC
Definition elog.h:44
#define DEBUG1
Definition elog.h:31
#define ERROR
Definition elog.h:40
int int int errdetail_log(const char *fmt,...) pg_attribute_printf(1
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
int int int int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
int MyProcPid
Definition globals.c:49
ProcNumber MyProcNumber
Definition globals.c:92
bool IsUnderPostmaster
Definition globals.c:122
int MaxConnections
Definition globals.c:145
int MaxBackends
Definition globals.c:149
struct Latch * MyLatch
Definition globals.c:65
int max_worker_processes
Definition globals.c:146
static dlist_node * dlist_pop_head_node(dlist_head *head)
Definition ilist.h:450
#define dlist_foreach(iter, lhead)
Definition ilist.h:623
static void dlist_init(dlist_head *head)
Definition ilist.h:314
static void dclist_push_tail(dclist_head *head, dlist_node *node)
Definition ilist.h:709
static void dlist_delete(dlist_node *node)
Definition ilist.h:405
static bool dclist_is_empty(const dclist_head *head)
Definition ilist.h:682
static bool dlist_node_is_detached(const dlist_node *node)
Definition ilist.h:525
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition ilist.h:347
static bool dlist_is_empty(const dlist_head *head)
Definition ilist.h:336
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition ilist.h:364
static void dclist_delete_from_thoroughly(dclist_head *head, dlist_node *node)
Definition ilist.h:776
static void dclist_insert_before(dclist_head *head, dlist_node *before, dlist_node *node)
Definition ilist.h:745
#define dclist_foreach_modify(iter, lhead)
Definition ilist.h:973
static void dlist_node_init(dlist_node *node)
Definition ilist.h:325
#define dlist_container(type, membername, ptr)
Definition ilist.h:593
#define dclist_foreach(iter, lhead)
Definition ilist.h:970
#define INJECTION_POINT(name, arg)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
int j
Definition isn.c:78
int i
Definition isn.c:77
void OwnLatch(Latch *latch)
Definition latch.c:126
void DisownLatch(Latch *latch)
Definition latch.c:144
void InitSharedLatch(Latch *latch)
Definition latch.c:93
void SetLatch(Latch *latch)
Definition latch.c:290
void ResetLatch(Latch *latch)
Definition latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition latch.c:172
void DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
Definition lmgr.c:1249
void GrantAwaitedLock(void)
Definition lock.c:1897
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
Definition lock.c:1666
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition lock.c:3077
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
Definition lock.c:2054
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition lock.c:2315
void ResetAwaitedLock(void)
Definition lock.c:1915
void AbortStrongLockAcquire(void)
Definition lock.c:1868
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition lock.c:4233
LOCALLOCK * GetAwaitedLock(void)
Definition lock.c:1906
int FastPathLockGroupsPerBackend
Definition lock.c:205
uint32 LockTagHashCode(const LOCKTAG *locktag)
Definition lock.c:554
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
Definition lock.c:1537
#define LockHashPartitionLock(hashcode)
Definition lock.h:357
#define InvalidLocalTransactionId
Definition lock.h:68
DeadLockState
Definition lock.h:340
@ DS_HARD_DEADLOCK
Definition lock.h:344
@ DS_BLOCKED_BY_AUTOVACUUM
Definition lock.h:345
@ DS_NO_DEADLOCK
Definition lock.h:342
@ DS_NOT_YET_CHECKED
Definition lock.h:341
@ DS_SOFT_DEADLOCK
Definition lock.h:343
#define LOCKBIT_ON(lockmode)
Definition lock.h:87
#define LockHashPartitionLockByProc(leader_pgproc)
Definition lock.h:372
#define LockHashPartitionLockByIndex(i)
Definition lock.h:360
int LOCKMODE
Definition lockdefs.h:26
#define AccessExclusiveLock
Definition lockdefs.h:43
int LOCKMASK
Definition lockdefs.h:25
#define DEFAULT_LOCKMETHOD
Definition locktag.h:25
#define USER_LOCKMETHOD
Definition locktag.h:26
bool LWLockHeldByMe(LWLock *lock)
Definition lwlock.c:1885
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1929
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
void LWLockReleaseAll(void)
Definition lwlock.c:1866
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition lwlock.c:670
void InitLWLockAccess(void)
Definition lwlock.c:506
@ LW_WS_NOT_WAITING
Definition lwlock.h:30
#define NUM_LOCK_PARTITIONS
Definition lwlock.h:87
@ LW_SHARED
Definition lwlock.h:105
@ LW_EXCLUSIVE
Definition lwlock.h:104
Size add_size(Size s1, Size s2)
Definition mcxt.c:1733
void pfree(void *pointer)
Definition mcxt.c:1619
Size mul_size(Size s1, Size s2)
Definition mcxt.c:1752
#define RESUME_INTERRUPTS()
Definition miscadmin.h:138
#define AmAutoVacuumWorkerProcess()
Definition miscadmin.h:389
#define AmBackgroundWorkerProcess()
Definition miscadmin.h:390
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
#define AmWalSenderProcess()
Definition miscadmin.h:391
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define AmSpecialWorkerProcess()
Definition miscadmin.h:405
@ B_WAL_WRITER
Definition miscadmin.h:371
@ B_CHECKPOINTER
Definition miscadmin.h:366
@ B_AUTOVAC_LAUNCHER
Definition miscadmin.h:347
void SwitchToSharedLatch(void)
Definition miscinit.c:216
BackendType MyBackendType
Definition miscinit.c:65
void SwitchBackToLocalLatch(void)
Definition miscinit.c:243
static char * errmsg
static char buf[DEFAULT_XLOG_SEG_SIZE]
int64 PgStat_Counter
Definition pgstat.h:71
void pgstat_count_lock_waits(uint8 locktag_type, PgStat_Counter usecs)
void RegisterPostmasterChildActive(void)
Definition pmsignal.c:289
void PGSemaphoreShmemRequest(int maxSemas)
Definition posix_sema.c:165
void PGSemaphoreReset(PGSemaphore sema)
Definition posix_sema.c:288
void PGSemaphoreInit(int maxSemas)
Definition posix_sema.c:198
PGSemaphore PGSemaphoreCreate(void)
Definition posix_sema.c:255
uint64_t Datum
Definition postgres.h:70
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define NON_EXEC_STATIC
Definition postgres.h:573
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define NUM_AUXILIARY_PROCS
Definition proc.h:529
#define FastPathLockSlotsPerBackend()
Definition proc.h:97
#define GetPGProcByNumber(n)
Definition proc.h:506
#define FIRST_PREPARED_XACT_PROC_NUMBER
Definition proc.h:531
#define PROC_VACUUM_FOR_WRAPAROUND
Definition proc.h:64
#define GetNumberFromPGProc(proc)
Definition proc.h:507
#define NUM_SPECIAL_WORKER_PROCS
Definition proc.h:516
ProcWaitStatus
Definition proc.h:144
@ PROC_WAIT_STATUS_OK
Definition proc.h:145
@ PROC_WAIT_STATUS_WAITING
Definition proc.h:146
@ PROC_WAIT_STATUS_ERROR
Definition proc.h:147
#define PROC_IS_AUTOVACUUM
Definition proc.h:61
void ProcArrayAdd(PGPROC *proc)
Definition procarray.c:464
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:561
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
int ProcNumber
Definition procnumber.h:24
void set_spins_per_delay(int shared_spins_per_delay)
Definition s_lock.c:207
int update_spins_per_delay(int shared_spins_per_delay)
Definition s_lock.c:218
#define DEFAULT_SPINS_PER_DELAY
Definition s_lock.h:718
#define SHMEM_ATTACH_UNKNOWN_SIZE
Definition shmem.h:69
#define ShmemRequestStruct(...)
Definition shmem.h:176
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56
static void SpinLockInit(volatile slock_t *lock)
Definition spin.h:50
ProcWaitStatus JoinWaitQueue(LOCALLOCK *locallock, LockMethod lockMethodTable, bool dontWait)
Definition proc.c:1209
void ProcSendSignal(ProcNumber procNumber)
Definition proc.c:2091
bool log_lock_waits
Definition proc.c:68
int IdleSessionTimeout
Definition proc.c:67
PGPROC * MyProc
Definition proc.c:71
void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus)
Definition proc.c:1812
int StatementTimeout
Definition proc.c:63
const ShmemCallbacks ProcGlobalShmemCallbacks
Definition proc.c:83
bool HaveNFreeProcs(int n, int *nfree)
Definition proc.c:797
static void RemoveProcFromArray(int code, Datum arg)
Definition proc.c:923
void InitAuxiliaryProcess(void)
Definition proc.c:623
PGPROC * PreparedXactProcs
Definition proc.c:78
static void * FastPathLockArrayShmemPtr
Definition proc.c:76
int IdleInTransactionSessionTimeout
Definition proc.c:65
void GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf, StringInfo lock_waiters_sbuf, int *lockHoldersNum)
Definition proc.c:2005
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
Definition proc.c:77
static void * AllProcsShmemPtr
Definition proc.c:75
int GetStartupBufferPinWaitBufId(void)
Definition proc.c:781
ProcWaitStatus ProcSleep(LOCALLOCK *locallock)
Definition proc.c:1378
int DeadlockTimeout
Definition proc.c:62
int TransactionTimeout
Definition proc.c:66
static void ProcGlobalShmemRequest(void *arg)
Definition proc.c:147
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
Definition proc.c:1840
PROC_HDR * ProcGlobal
Definition proc.c:74
int ProcGlobalSemas(void)
Definition proc.c:130
void ProcReleaseLocks(bool isCommit)
Definition proc.c:906
void LockErrorCleanup(void)
Definition proc.c:828
bool BecomeLockGroupMember(PGPROC *leader, int pid)
Definition proc.c:2136
static void ProcGlobalShmemInit(void *arg)
Definition proc.c:221
void BecomeLockGroupLeader(void)
Definition proc.c:2106
static size_t ProcGlobalAllProcsShmemSize
Definition proc.c:89
static void ProcKill(int code, Datum arg)
Definition proc.c:934
void InitProcess(void)
Definition proc.c:393
void CheckDeadLockAlert(void)
Definition proc.c:1978
void InitProcessPhase2(void)
Definition proc.c:588
static size_t FastPathLockArrayShmemSize
Definition proc.c:90
static volatile sig_atomic_t got_deadlock_timeout
Definition proc.c:93
PGPROC * AuxiliaryPidGetProc(int pid)
Definition proc.c:1160
void SetStartupBufferPinWaitBufId(int bufid)
Definition proc.c:769
void ProcWaitForSignal(uint32 wait_event_info)
Definition proc.c:2079
static Size CalculateFastPathLockShmemSize(void)
Definition proc.c:105
int LockTimeout
Definition proc.c:64
static void AuxiliaryProcKill(int code, Datum arg)
Definition proc.c:1095
static DeadLockState CheckDeadLock(void)
Definition proc.c:1887
static uint32 TotalProcs
Definition proc.c:88
void CheckRecoveryConflictDeadlock(void)
Definition standby.c:907
bool log_recovery_conflict_waits
Definition standby.c:43
void LogRecoveryConflict(RecoveryConflictReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition standby.c:275
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition standby.c:626
@ RECOVERY_CONFLICT_LOCK
Definition standby.h:40
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
uint8 locktag_lockmethodid
Definition locktag.h:71
Definition lock.h:140
LOCKTAG tag
Definition lock.h:142
dclist_head waitProcs
Definition lock.h:148
LOCKMASK waitMask
Definition lock.h:146
dlist_head procLocks
Definition lock.h:147
Definition proc.h:179
LWLock fpInfoLock
Definition proc.h:324
TransactionId xmin
Definition proc.h:242
bool procArrayGroupMember
Definition proc.h:350
LocalTransactionId lxid
Definition proc.h:231
PROCLOCK * waitProcLock
Definition proc.h:306
dlist_node freeProcsLink
Definition proc.h:186
XLogRecPtr clogGroupMemberLsn
Definition proc.h:371
pg_atomic_uint32 procArrayGroupNext
Definition proc.h:352
uint8 lwWaitMode
Definition proc.h:284
dlist_head lockGroupMembers
Definition proc.h:299
uint32 wait_event_info
Definition proc.h:378
dlist_head * procgloballist
Definition proc.h:185
Oid * fpRelId
Definition proc.h:326
BackendType backendType
Definition proc.h:198
uint8 statusFlags
Definition proc.h:210
TransactionId clogGroupMemberXid
Definition proc.h:366
Oid databaseId
Definition proc.h:201
int64 clogGroupMemberPage
Definition proc.h:369
bool clogGroupMember
Definition proc.h:364
uint64 * fpLockBits
Definition proc.h:325
pg_atomic_uint64 waitStart
Definition proc.h:311
bool fpVXIDLock
Definition proc.h:327
ProcNumber procNumber
Definition proc.h:226
int pid
Definition proc.h:197
XLogRecPtr waitLSN
Definition proc.h:341
dlist_node syncRepLinks
Definition proc.h:343
int syncRepState
Definition proc.h:342
pg_atomic_uint32 clogGroupNext
Definition proc.h:365
dlist_node lockGroupLink
Definition proc.h:300
XidStatus clogGroupMemberXidStatus
Definition proc.h:367
LOCK * waitLock
Definition proc.h:304
TransactionId xid
Definition proc.h:237
LOCKMODE waitLockMode
Definition proc.h:307
int delayChkptFlags
Definition proc.h:260
dlist_node waitLink
Definition proc.h:305
PGPROC * lockGroupLeader
Definition proc.h:298
pg_atomic_uint32 pendingRecoveryConflicts
Definition proc.h:270
LocalTransactionId fpLocalTransactionId
Definition proc.h:328
TransactionId procArrayGroupMemberXid
Definition proc.h:358
LOCKMASK heldLocks
Definition proc.h:308
struct PGPROC::@134 vxid
PGSemaphore sem
Definition proc.h:258
dlist_head myProcLocks[NUM_LOCK_PARTITIONS]
Definition proc.h:321
Oid roleId
Definition proc.h:202
ProcWaitStatus waitStatus
Definition proc.h:314
Oid tempNamespaceId
Definition proc.h:204
uint8 lwWaiting
Definition proc.h:283
Latch procLatch
Definition proc.h:256
LOCKMASK holdMask
Definition lock.h:207
uint8 * statusFlags
Definition proc.h:456
XidCacheStatus * subxidStates
Definition proc.h:450
dlist_head autovacFreeProcs
Definition proc.h:473
dlist_head freeProcs
Definition proc.h:471
pg_atomic_uint32 checkpointerProc
Definition proc.h:489
pg_atomic_uint32 avLauncherProc
Definition proc.h:491
slock_t freeProcsLock
Definition proc.h:468
int startupBufferPinWaitBufId
Definition proc.h:496
PGPROC * allProcs
Definition proc.h:441
pg_atomic_uint32 clogGroupFirst
Definition proc.h:482
int spins_per_delay
Definition proc.h:494
TransactionId * xids
Definition proc.h:444
dlist_head walsenderFreeProcs
Definition proc.h:477
pg_atomic_uint32 walwriterProc
Definition proc.h:488
dlist_head bgworkerFreeProcs
Definition proc.h:475
pg_atomic_uint32 procArrayGroupFirst
Definition proc.h:480
uint32 allProcCount
Definition proc.h:459
ShmemRequestCallback request_fn
Definition shmem.h:133
dlist_node * cur
Definition ilist.h:179
Definition type.h:97
void SyncRepCleanupAtProcExit(void)
Definition syncrep.c:426
#define SYNC_REP_NOT_WAITING
Definition syncrep.h:30
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition timeout.c:560
TimestampTz get_timeout_start_time(TimeoutId id)
Definition timeout.c:813
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition timeout.c:685
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition timeout.c:630
void disable_timeouts(const DisableTimeoutParams *timeouts, int count)
Definition timeout.c:718
@ LOCK_TIMEOUT
Definition timeout.h:28
@ DEADLOCK_TIMEOUT
Definition timeout.h:27
@ TMPARAM_AFTER
Definition timeout.h:53
#define InvalidTransactionId
Definition transam.h:31
int max_prepared_xacts
Definition twophase.c:118
#define PG_WAIT_LOCK
void pgstat_set_wait_event_storage(uint32 *wait_event_info)
Definition wait_event.c:319
void pgstat_reset_wait_event_storage(void)
Definition wait_event.c:331
const char * name
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET
int max_wal_senders
Definition walsender.c:141
#define kill(pid, sig)
Definition win32_port.h:507
bool RecoveryInProgress(void)
Definition xlog.c:6835
#define InvalidXLogRecPtr
Definition xlogdefs.h:28
bool InRecovery
Definition xlogutils.c:50
#define InHotStandby
Definition xlogutils.h:60
void WaitLSNCleanup(void)
Definition xlogwait.c:366