Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * procarray.c
4 : * POSTGRES process array code.
5 : *
6 : *
7 : * This module maintains arrays of PGPROC substructures, as well as associated
8 : * arrays in ProcGlobal, for all active backends. Although there are several
9 : * uses for this, the principal one is as a means of determining the set of
10 : * currently running transactions.
11 : *
12 : * Because of various subtle race conditions it is critical that a backend
13 : * hold the correct locks while setting or clearing its xid (in
14 : * ProcGlobal->xids[]/MyProc->xid). See notes in
15 : * src/backend/access/transam/README.
16 : *
17 : * The process arrays now also include structures representing prepared
18 : * transactions. The xid and subxids fields of these are valid, as are the
19 : * myProcLocks lists. They can be distinguished from regular backend PGPROCs
20 : * at need by checking for pid == 0.
21 : *
22 : * During hot standby, we also keep a list of XIDs representing transactions
23 : * that are known to be running on the primary (or more precisely, were running
24 : * as of the current point in the WAL stream). This list is kept in the
25 : * KnownAssignedXids array, and is updated by watching the sequence of
26 : * arriving XIDs. This is necessary because if we leave those XIDs out of
27 : * snapshots taken for standby queries, then they will appear to be already
28 : * complete, leading to MVCC failures. Note that in hot standby, the PGPROC
29 : * array represents standby processes, which by definition are not running
30 : * transactions that have XIDs.
31 : *
32 : * It is perhaps possible for a backend on the primary to terminate without
33 : * writing an abort record for its transaction. While that shouldn't really
34 : * happen, it would tie up KnownAssignedXids indefinitely, so we protect
35 : * ourselves by pruning the array when a valid list of running XIDs arrives.
36 : *
37 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
38 : * Portions Copyright (c) 1994, Regents of the University of California
39 : *
40 : *
41 : * IDENTIFICATION
42 : * src/backend/storage/ipc/procarray.c
43 : *
44 : *-------------------------------------------------------------------------
45 : */
46 : #include "postgres.h"
47 :
48 : #include <signal.h>
49 :
50 : #include "access/subtrans.h"
51 : #include "access/transam.h"
52 : #include "access/twophase.h"
53 : #include "access/xact.h"
54 : #include "access/xlogutils.h"
55 : #include "catalog/catalog.h"
56 : #include "catalog/pg_authid.h"
57 : #include "miscadmin.h"
58 : #include "pgstat.h"
59 : #include "postmaster/bgworker.h"
60 : #include "port/pg_lfind.h"
61 : #include "storage/proc.h"
62 : #include "storage/procarray.h"
63 : #include "utils/acl.h"
64 : #include "utils/builtins.h"
65 : #include "utils/injection_point.h"
66 : #include "utils/lsyscache.h"
67 : #include "utils/rel.h"
68 : #include "utils/snapmgr.h"
69 :
70 : #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
71 :
72 : /* Our shared memory area */
73 : typedef struct ProcArrayStruct
74 : {
75 : int numProcs; /* number of valid procs entries */
76 : int maxProcs; /* allocated size of procs array */
77 :
78 : /*
79 : * Known assigned XIDs handling
80 : */
81 : int maxKnownAssignedXids; /* allocated size of array */
82 : int numKnownAssignedXids; /* current # of valid entries */
83 : int tailKnownAssignedXids; /* index of oldest valid element */
84 : int headKnownAssignedXids; /* index of newest element, + 1 */
85 :
86 : /*
87 : * Highest subxid that has been removed from KnownAssignedXids array to
88 : * prevent overflow; or InvalidTransactionId if none. We track this for
89 : * similar reasons to tracking overflowing cached subxids in PGPROC
90 : * entries. Must hold exclusive ProcArrayLock to change this, and shared
91 : * lock to read it.
92 : */
93 : TransactionId lastOverflowedXid;
94 :
95 : /* oldest xmin of any replication slot */
96 : TransactionId replication_slot_xmin;
97 : /* oldest catalog xmin of any replication slot */
98 : TransactionId replication_slot_catalog_xmin;
99 :
100 : /* indexes into allProcs[], has PROCARRAY_MAXPROCS entries */
101 : int pgprocnos[FLEXIBLE_ARRAY_MEMBER];
102 : } ProcArrayStruct;
103 :
104 : /*
105 : * State for the GlobalVisTest* family of functions. Those functions can
106 : * e.g. be used to decide if a deleted row can be removed without violating
107 : * MVCC semantics: If the deleted row's xmax is not considered to be running
108 : * by anyone, the row can be removed.
109 : *
110 : * To avoid slowing down GetSnapshotData(), we don't calculate a precise
111 : * cutoff XID while building a snapshot (looking at the frequently changing
112 : * xmins scales badly). Instead we compute two boundaries while building the
113 : * snapshot:
114 : *
115 : * 1) definitely_needed, indicating that rows deleted by XIDs >=
116 : * definitely_needed are definitely still visible.
117 : *
118 : * 2) maybe_needed, indicating that rows deleted by XIDs < maybe_needed can
119 : * definitely be removed
120 : *
121 : * When testing an XID that falls in between the two (i.e. XID >= maybe_needed
122 : * && XID < definitely_needed), the boundaries can be recomputed (using
123 : * ComputeXidHorizons()) to get a more accurate answer. This is cheaper than
124 : * maintaining an accurate value all the time.
125 : *
126 : * As it is not cheap to compute accurate boundaries, we limit the number of
127 : * times that happens in short succession. See GlobalVisTestShouldUpdate().
128 : *
129 : *
130 : * There are three backend lifetime instances of this struct, optimized for
131 : * different types of relations. As e.g. a normal user defined table in one
132 : * database is inaccessible to backends connected to another database, a test
133 : * specific to a relation can be more aggressive than a test for a shared
134 : * relation. Currently we track four different states:
135 : *
136 : * 1) GlobalVisSharedRels, which only considers an XID's
137 : * effects visible-to-everyone if neither snapshots in any database, nor a
138 : * replication slot's xmin, nor a replication slot's catalog_xmin might
139 : * still consider XID as running.
140 : *
141 : * 2) GlobalVisCatalogRels, which only considers an XID's
142 : * effects visible-to-everyone if neither snapshots in the current
143 : * database, nor a replication slot's xmin, nor a replication slot's
144 : * catalog_xmin might still consider XID as running.
145 : *
146 : * I.e. the difference to GlobalVisSharedRels is that
147 : * snapshot in other databases are ignored.
148 : *
149 : * 3) GlobalVisDataRels, which only considers an XID's
150 : * effects visible-to-everyone if neither snapshots in the current
151 : * database, nor a replication slot's xmin consider XID as running.
152 : *
153 : * I.e. the difference to GlobalVisCatalogRels is that
154 : * replication slot's catalog_xmin is not taken into account.
155 : *
156 : * 4) GlobalVisTempRels, which only considers the current session, as temp
157 : * tables are not visible to other sessions.
158 : *
159 : * GlobalVisTestFor(relation) returns the appropriate state
160 : * for the relation.
161 : *
162 : * The boundaries are FullTransactionIds instead of TransactionIds to avoid
163 : * wraparound dangers. There e.g. would otherwise exist no procarray state to
164 : * prevent maybe_needed to become old enough after the GetSnapshotData()
165 : * call.
166 : *
167 : * The typedef is in the header.
168 : */
169 : struct GlobalVisState
170 : {
171 : /* XIDs >= are considered running by some backend */
172 : FullTransactionId definitely_needed;
173 :
174 : /* XIDs < are not considered to be running by any backend */
175 : FullTransactionId maybe_needed;
176 : };
177 :
178 : /*
179 : * Result of ComputeXidHorizons().
180 : */
181 : typedef struct ComputeXidHorizonsResult
182 : {
183 : /*
184 : * The value of TransamVariables->latestCompletedXid when
185 : * ComputeXidHorizons() held ProcArrayLock.
186 : */
187 : FullTransactionId latest_completed;
188 :
189 : /*
190 : * The same for procArray->replication_slot_xmin and
191 : * procArray->replication_slot_catalog_xmin.
192 : */
193 : TransactionId slot_xmin;
194 : TransactionId slot_catalog_xmin;
195 :
196 : /*
197 : * Oldest xid that any backend might still consider running. This needs to
198 : * include processes running VACUUM, in contrast to the normal visibility
199 : * cutoffs, as vacuum needs to be able to perform pg_subtrans lookups when
200 : * determining visibility, but doesn't care about rows above its xmin to
201 : * be removed.
202 : *
203 : * This likely should only be needed to determine whether pg_subtrans can
204 : * be truncated. It currently includes the effects of replication slots,
205 : * for historical reasons. But that could likely be changed.
206 : */
207 : TransactionId oldest_considered_running;
208 :
209 : /*
210 : * Oldest xid for which deleted tuples need to be retained in shared
211 : * tables.
212 : *
213 : * This includes the effects of replication slots. If that's not desired,
214 : * look at shared_oldest_nonremovable_raw;
215 : */
216 : TransactionId shared_oldest_nonremovable;
217 :
218 : /*
219 : * Oldest xid that may be necessary to retain in shared tables. This is
220 : * the same as shared_oldest_nonremovable, except that is not affected by
221 : * replication slot's catalog_xmin.
222 : *
223 : * This is mainly useful to be able to send the catalog_xmin to upstream
224 : * streaming replication servers via hot_standby_feedback, so they can
225 : * apply the limit only when accessing catalog tables.
226 : */
227 : TransactionId shared_oldest_nonremovable_raw;
228 :
229 : /*
230 : * Oldest xid for which deleted tuples need to be retained in non-shared
231 : * catalog tables.
232 : */
233 : TransactionId catalog_oldest_nonremovable;
234 :
235 : /*
236 : * Oldest xid for which deleted tuples need to be retained in normal user
237 : * defined tables.
238 : */
239 : TransactionId data_oldest_nonremovable;
240 :
241 : /*
242 : * Oldest xid for which deleted tuples need to be retained in this
243 : * session's temporary tables.
244 : */
245 : TransactionId temp_oldest_nonremovable;
246 : } ComputeXidHorizonsResult;
247 :
248 : /*
249 : * Return value for GlobalVisHorizonKindForRel().
250 : */
251 : typedef enum GlobalVisHorizonKind
252 : {
253 : VISHORIZON_SHARED,
254 : VISHORIZON_CATALOG,
255 : VISHORIZON_DATA,
256 : VISHORIZON_TEMP,
257 : } GlobalVisHorizonKind;
258 :
259 : /*
260 : * Reason codes for KnownAssignedXidsCompress().
261 : */
262 : typedef enum KAXCompressReason
263 : {
264 : KAX_NO_SPACE, /* need to free up space at array end */
265 : KAX_PRUNE, /* we just pruned old entries */
266 : KAX_TRANSACTION_END, /* we just committed/removed some XIDs */
267 : KAX_STARTUP_PROCESS_IDLE, /* startup process is about to sleep */
268 : } KAXCompressReason;
269 :
270 :
271 : static ProcArrayStruct *procArray;
272 :
273 : static PGPROC *allProcs;
274 :
275 : /*
276 : * Cache to reduce overhead of repeated calls to TransactionIdIsInProgress()
277 : */
278 : static TransactionId cachedXidIsNotInProgress = InvalidTransactionId;
279 :
280 : /*
281 : * Bookkeeping for tracking emulated transactions in recovery
282 : */
283 : static TransactionId *KnownAssignedXids;
284 : static bool *KnownAssignedXidsValid;
285 : static TransactionId latestObservedXid = InvalidTransactionId;
286 :
287 : /*
288 : * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
289 : * the highest xid that might still be running that we don't have in
290 : * KnownAssignedXids.
291 : */
292 : static TransactionId standbySnapshotPendingXmin;
293 :
294 : /*
295 : * State for visibility checks on different types of relations. See struct
296 : * GlobalVisState for details. As shared, catalog, normal and temporary
297 : * relations can have different horizons, one such state exists for each.
298 : */
299 : static GlobalVisState GlobalVisSharedRels;
300 : static GlobalVisState GlobalVisCatalogRels;
301 : static GlobalVisState GlobalVisDataRels;
302 : static GlobalVisState GlobalVisTempRels;
303 :
304 : /*
305 : * This backend's RecentXmin at the last time the accurate xmin horizon was
306 : * recomputed, or InvalidTransactionId if it has not. Used to limit how many
307 : * times accurate horizons are recomputed. See GlobalVisTestShouldUpdate().
308 : */
309 : static TransactionId ComputeXidHorizonsResultLastXmin;
310 :
311 : #ifdef XIDCACHE_DEBUG
312 :
313 : /* counters for XidCache measurement */
314 : static long xc_by_recent_xmin = 0;
315 : static long xc_by_known_xact = 0;
316 : static long xc_by_my_xact = 0;
317 : static long xc_by_latest_xid = 0;
318 : static long xc_by_main_xid = 0;
319 : static long xc_by_child_xid = 0;
320 : static long xc_by_known_assigned = 0;
321 : static long xc_no_overflow = 0;
322 : static long xc_slow_answer = 0;
323 :
324 : #define xc_by_recent_xmin_inc() (xc_by_recent_xmin++)
325 : #define xc_by_known_xact_inc() (xc_by_known_xact++)
326 : #define xc_by_my_xact_inc() (xc_by_my_xact++)
327 : #define xc_by_latest_xid_inc() (xc_by_latest_xid++)
328 : #define xc_by_main_xid_inc() (xc_by_main_xid++)
329 : #define xc_by_child_xid_inc() (xc_by_child_xid++)
330 : #define xc_by_known_assigned_inc() (xc_by_known_assigned++)
331 : #define xc_no_overflow_inc() (xc_no_overflow++)
332 : #define xc_slow_answer_inc() (xc_slow_answer++)
333 :
334 : static void DisplayXidCache(void);
335 : #else /* !XIDCACHE_DEBUG */
336 :
337 : #define xc_by_recent_xmin_inc() ((void) 0)
338 : #define xc_by_known_xact_inc() ((void) 0)
339 : #define xc_by_my_xact_inc() ((void) 0)
340 : #define xc_by_latest_xid_inc() ((void) 0)
341 : #define xc_by_main_xid_inc() ((void) 0)
342 : #define xc_by_child_xid_inc() ((void) 0)
343 : #define xc_by_known_assigned_inc() ((void) 0)
344 : #define xc_no_overflow_inc() ((void) 0)
345 : #define xc_slow_answer_inc() ((void) 0)
346 : #endif /* XIDCACHE_DEBUG */
347 :
348 : /* Primitives for KnownAssignedXids array handling for standby */
349 : static void KnownAssignedXidsCompress(KAXCompressReason reason, bool haveLock);
350 : static void KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid,
351 : bool exclusive_lock);
352 : static bool KnownAssignedXidsSearch(TransactionId xid, bool remove);
353 : static bool KnownAssignedXidExists(TransactionId xid);
354 : static void KnownAssignedXidsRemove(TransactionId xid);
355 : static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
356 : TransactionId *subxids);
357 : static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
358 : static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
359 : static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
360 : TransactionId *xmin,
361 : TransactionId xmax);
362 : static TransactionId KnownAssignedXidsGetOldestXmin(void);
363 : static void KnownAssignedXidsDisplay(int trace_level);
364 : static void KnownAssignedXidsReset(void);
365 : static inline void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid);
366 : static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid);
367 : static void MaintainLatestCompletedXid(TransactionId latestXid);
368 : static void MaintainLatestCompletedXidRecovery(TransactionId latestXid);
369 :
370 : static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
371 : TransactionId xid);
372 : static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
373 :
374 : /*
375 : * Report shared-memory space needed by ProcArrayShmemInit
376 : */
377 : Size
378 4254 : ProcArrayShmemSize(void)
379 : {
380 : Size size;
381 :
382 : /* Size of the ProcArray structure itself */
383 : #define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
384 :
385 4254 : size = offsetof(ProcArrayStruct, pgprocnos);
386 4254 : size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS));
387 :
388 : /*
389 : * During Hot Standby processing we have a data structure called
390 : * KnownAssignedXids, created in shared memory. Local data structures are
391 : * also created in various backends during GetSnapshotData(),
392 : * TransactionIdIsInProgress() and GetRunningTransactionData(). All of the
393 : * main structures created in those functions must be identically sized,
394 : * since we may at times copy the whole of the data structures around. We
395 : * refer to this size as TOTAL_MAX_CACHED_SUBXIDS.
396 : *
397 : * Ideally we'd only create this structure if we were actually doing hot
398 : * standby in the current run, but we don't know that yet at the time
399 : * shared memory is being set up.
400 : */
401 : #define TOTAL_MAX_CACHED_SUBXIDS \
402 : ((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)
403 :
404 4254 : if (EnableHotStandby)
405 : {
406 4230 : size = add_size(size,
407 : mul_size(sizeof(TransactionId),
408 4230 : TOTAL_MAX_CACHED_SUBXIDS));
409 4230 : size = add_size(size,
410 4230 : mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
411 : }
412 :
413 4254 : return size;
414 : }
415 :
416 : /*
417 : * Initialize the shared PGPROC array during postmaster startup.
418 : */
419 : void
420 2280 : ProcArrayShmemInit(void)
421 : {
422 : bool found;
423 :
424 : /* Create or attach to the ProcArray shared structure */
425 2280 : procArray = (ProcArrayStruct *)
426 2280 : ShmemInitStruct("Proc Array",
427 : add_size(offsetof(ProcArrayStruct, pgprocnos),
428 : mul_size(sizeof(int),
429 2280 : PROCARRAY_MAXPROCS)),
430 : &found);
431 :
432 2280 : if (!found)
433 : {
434 : /*
435 : * We're the first - initialize.
436 : */
437 2280 : procArray->numProcs = 0;
438 2280 : procArray->maxProcs = PROCARRAY_MAXPROCS;
439 2280 : procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
440 2280 : procArray->numKnownAssignedXids = 0;
441 2280 : procArray->tailKnownAssignedXids = 0;
442 2280 : procArray->headKnownAssignedXids = 0;
443 2280 : procArray->lastOverflowedXid = InvalidTransactionId;
444 2280 : procArray->replication_slot_xmin = InvalidTransactionId;
445 2280 : procArray->replication_slot_catalog_xmin = InvalidTransactionId;
446 2280 : TransamVariables->xactCompletionCount = 1;
447 : }
448 :
449 2280 : allProcs = ProcGlobal->allProcs;
450 :
451 : /* Create or attach to the KnownAssignedXids arrays too, if needed */
452 2280 : if (EnableHotStandby)
453 : {
454 2268 : KnownAssignedXids = (TransactionId *)
455 2268 : ShmemInitStruct("KnownAssignedXids",
456 : mul_size(sizeof(TransactionId),
457 2268 : TOTAL_MAX_CACHED_SUBXIDS),
458 : &found);
459 2268 : KnownAssignedXidsValid = (bool *)
460 2268 : ShmemInitStruct("KnownAssignedXidsValid",
461 2268 : mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
462 : &found);
463 : }
464 2280 : }
465 :
466 : /*
467 : * Add the specified PGPROC to the shared array.
468 : */
469 : void
470 37096 : ProcArrayAdd(PGPROC *proc)
471 : {
472 37096 : int pgprocno = GetNumberFromPGProc(proc);
473 37096 : ProcArrayStruct *arrayP = procArray;
474 : int index;
475 : int movecount;
476 :
477 : /* See ProcGlobal comment explaining why both locks are held */
478 37096 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
479 37096 : LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
480 :
481 37096 : if (arrayP->numProcs >= arrayP->maxProcs)
482 : {
483 : /*
484 : * Oops, no room. (This really shouldn't happen, since there is a
485 : * fixed supply of PGPROC structs too, and so we should have failed
486 : * earlier.)
487 : */
488 0 : ereport(FATAL,
489 : (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
490 : errmsg("sorry, too many clients already")));
491 : }
492 :
493 : /*
494 : * Keep the procs array sorted by (PGPROC *) so that we can utilize
495 : * locality of references much better. This is useful while traversing the
496 : * ProcArray because there is an increased likelihood of finding the next
497 : * PGPROC structure in the cache.
498 : *
499 : * Since the occurrence of adding/removing a proc is much lower than the
500 : * access to the ProcArray itself, the overhead should be marginal
501 : */
502 89234 : for (index = 0; index < arrayP->numProcs; index++)
503 : {
504 80028 : int this_procno = arrayP->pgprocnos[index];
505 :
506 : Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
507 : Assert(allProcs[this_procno].pgxactoff == index);
508 :
509 : /* If we have found our right position in the array, break */
510 80028 : if (this_procno > pgprocno)
511 27890 : break;
512 : }
513 :
514 37096 : movecount = arrayP->numProcs - index;
515 37096 : memmove(&arrayP->pgprocnos[index + 1],
516 37096 : &arrayP->pgprocnos[index],
517 : movecount * sizeof(*arrayP->pgprocnos));
518 37096 : memmove(&ProcGlobal->xids[index + 1],
519 37096 : &ProcGlobal->xids[index],
520 : movecount * sizeof(*ProcGlobal->xids));
521 37096 : memmove(&ProcGlobal->subxidStates[index + 1],
522 37096 : &ProcGlobal->subxidStates[index],
523 : movecount * sizeof(*ProcGlobal->subxidStates));
524 37096 : memmove(&ProcGlobal->statusFlags[index + 1],
525 37096 : &ProcGlobal->statusFlags[index],
526 : movecount * sizeof(*ProcGlobal->statusFlags));
527 :
528 37096 : arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
529 37096 : proc->pgxactoff = index;
530 37096 : ProcGlobal->xids[index] = proc->xid;
531 37096 : ProcGlobal->subxidStates[index] = proc->subxidStatus;
532 37096 : ProcGlobal->statusFlags[index] = proc->statusFlags;
533 :
534 37096 : arrayP->numProcs++;
535 :
536 : /* adjust pgxactoff for all following PGPROCs */
537 37096 : index++;
538 101740 : for (; index < arrayP->numProcs; index++)
539 : {
540 64644 : int procno = arrayP->pgprocnos[index];
541 :
542 : Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
543 : Assert(allProcs[procno].pgxactoff == index - 1);
544 :
545 64644 : allProcs[procno].pgxactoff = index;
546 : }
547 :
548 : /*
549 : * Release in reversed acquisition order, to reduce frequency of having to
550 : * wait for XidGenLock while holding ProcArrayLock.
551 : */
552 37096 : LWLockRelease(XidGenLock);
553 37096 : LWLockRelease(ProcArrayLock);
554 37096 : }
555 :
556 : /*
557 : * Remove the specified PGPROC from the shared array.
558 : *
559 : * When latestXid is a valid XID, we are removing a live 2PC gxact from the
560 : * array, and thus causing it to appear as "not running" anymore. In this
561 : * case we must advance latestCompletedXid. (This is essentially the same
562 : * as ProcArrayEndTransaction followed by removal of the PGPROC, but we take
563 : * the ProcArrayLock only once, and don't damage the content of the PGPROC;
564 : * twophase.c depends on the latter.)
565 : */
566 : void
567 37048 : ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
568 : {
569 37048 : ProcArrayStruct *arrayP = procArray;
570 : int myoff;
571 : int movecount;
572 :
573 : #ifdef XIDCACHE_DEBUG
574 : /* dump stats at backend shutdown, but not prepared-xact end */
575 : if (proc->pid != 0)
576 : DisplayXidCache();
577 : #endif
578 :
579 : /* See ProcGlobal comment explaining why both locks are held */
580 37048 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
581 37048 : LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
582 :
583 37048 : myoff = proc->pgxactoff;
584 :
585 : Assert(myoff >= 0 && myoff < arrayP->numProcs);
586 : Assert(ProcGlobal->allProcs[arrayP->pgprocnos[myoff]].pgxactoff == myoff);
587 :
588 37048 : if (TransactionIdIsValid(latestXid))
589 : {
590 : Assert(TransactionIdIsValid(ProcGlobal->xids[myoff]));
591 :
592 : /* Advance global latestCompletedXid while holding the lock */
593 608 : MaintainLatestCompletedXid(latestXid);
594 :
595 : /* Same with xactCompletionCount */
596 608 : TransamVariables->xactCompletionCount++;
597 :
598 608 : ProcGlobal->xids[myoff] = InvalidTransactionId;
599 608 : ProcGlobal->subxidStates[myoff].overflowed = false;
600 608 : ProcGlobal->subxidStates[myoff].count = 0;
601 : }
602 : else
603 : {
604 : /* Shouldn't be trying to remove a live transaction here */
605 : Assert(!TransactionIdIsValid(ProcGlobal->xids[myoff]));
606 : }
607 :
608 : Assert(!TransactionIdIsValid(ProcGlobal->xids[myoff]));
609 : Assert(ProcGlobal->subxidStates[myoff].count == 0);
610 : Assert(ProcGlobal->subxidStates[myoff].overflowed == false);
611 :
612 37048 : ProcGlobal->statusFlags[myoff] = 0;
613 :
614 : /* Keep the PGPROC array sorted. See notes above */
615 37048 : movecount = arrayP->numProcs - myoff - 1;
616 37048 : memmove(&arrayP->pgprocnos[myoff],
617 37048 : &arrayP->pgprocnos[myoff + 1],
618 : movecount * sizeof(*arrayP->pgprocnos));
619 37048 : memmove(&ProcGlobal->xids[myoff],
620 37048 : &ProcGlobal->xids[myoff + 1],
621 : movecount * sizeof(*ProcGlobal->xids));
622 37048 : memmove(&ProcGlobal->subxidStates[myoff],
623 37048 : &ProcGlobal->subxidStates[myoff + 1],
624 : movecount * sizeof(*ProcGlobal->subxidStates));
625 37048 : memmove(&ProcGlobal->statusFlags[myoff],
626 37048 : &ProcGlobal->statusFlags[myoff + 1],
627 : movecount * sizeof(*ProcGlobal->statusFlags));
628 :
629 37048 : arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */
630 37048 : arrayP->numProcs--;
631 :
632 : /*
633 : * Adjust pgxactoff of following procs for removed PGPROC (note that
634 : * numProcs already has been decremented).
635 : */
636 108466 : for (int index = myoff; index < arrayP->numProcs; index++)
637 : {
638 71418 : int procno = arrayP->pgprocnos[index];
639 :
640 : Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
641 : Assert(allProcs[procno].pgxactoff - 1 == index);
642 :
643 71418 : allProcs[procno].pgxactoff = index;
644 : }
645 :
646 : /*
647 : * Release in reversed acquisition order, to reduce frequency of having to
648 : * wait for XidGenLock while holding ProcArrayLock.
649 : */
650 37048 : LWLockRelease(XidGenLock);
651 37048 : LWLockRelease(ProcArrayLock);
652 37048 : }
653 :
654 :
655 : /*
656 : * ProcArrayEndTransaction -- mark a transaction as no longer running
657 : *
658 : * This is used interchangeably for commit and abort cases. The transaction
659 : * commit/abort must already be reported to WAL and pg_xact.
660 : *
661 : * proc is currently always MyProc, but we pass it explicitly for flexibility.
662 : * latestXid is the latest Xid among the transaction's main XID and
663 : * subtransactions, or InvalidTransactionId if it has no XID. (We must ask
664 : * the caller to pass latestXid, instead of computing it from the PGPROC's
665 : * contents, because the subxid information in the PGPROC might be
666 : * incomplete.)
667 : */
668 : void
669 1005348 : ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
670 : {
671 1005348 : if (TransactionIdIsValid(latestXid))
672 : {
673 : /*
674 : * We must lock ProcArrayLock while clearing our advertised XID, so
675 : * that we do not exit the set of "running" transactions while someone
676 : * else is taking a snapshot. See discussion in
677 : * src/backend/access/transam/README.
678 : */
679 : Assert(TransactionIdIsValid(proc->xid));
680 :
681 : /*
682 : * If we can immediately acquire ProcArrayLock, we clear our own XID
683 : * and release the lock. If not, use group XID clearing to improve
684 : * efficiency.
685 : */
686 275658 : if (LWLockConditionalAcquire(ProcArrayLock, LW_EXCLUSIVE))
687 : {
688 275330 : ProcArrayEndTransactionInternal(proc, latestXid);
689 275330 : LWLockRelease(ProcArrayLock);
690 : }
691 : else
692 328 : ProcArrayGroupClearXid(proc, latestXid);
693 : }
694 : else
695 : {
696 : /*
697 : * If we have no XID, we don't need to lock, since we won't affect
698 : * anyone else's calculation of a snapshot. We might change their
699 : * estimate of global xmin, but that's OK.
700 : */
701 : Assert(!TransactionIdIsValid(proc->xid));
702 : Assert(proc->subxidStatus.count == 0);
703 : Assert(!proc->subxidStatus.overflowed);
704 :
705 729690 : proc->vxid.lxid = InvalidLocalTransactionId;
706 729690 : proc->xmin = InvalidTransactionId;
707 :
708 : /* be sure this is cleared in abort */
709 729690 : proc->delayChkptFlags = 0;
710 :
711 : /* must be cleared with xid/xmin: */
712 : /* avoid unnecessarily dirtying shared cachelines */
713 729690 : if (proc->statusFlags & PROC_VACUUM_STATE_MASK)
714 : {
715 : Assert(!LWLockHeldByMe(ProcArrayLock));
716 186558 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
717 : Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]);
718 186558 : proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;
719 186558 : ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags;
720 186558 : LWLockRelease(ProcArrayLock);
721 : }
722 : }
723 1005348 : }
724 :
725 : /*
726 : * Mark a write transaction as no longer running.
727 : *
728 : * We don't do any locking here; caller must handle that.
729 : */
730 : static inline void
731 275658 : ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
732 : {
733 275658 : int pgxactoff = proc->pgxactoff;
734 :
735 : /*
736 : * Note: we need exclusive lock here because we're going to change other
737 : * processes' PGPROC entries.
738 : */
739 : Assert(LWLockHeldByMeInMode(ProcArrayLock, LW_EXCLUSIVE));
740 : Assert(TransactionIdIsValid(ProcGlobal->xids[pgxactoff]));
741 : Assert(ProcGlobal->xids[pgxactoff] == proc->xid);
742 :
743 275658 : ProcGlobal->xids[pgxactoff] = InvalidTransactionId;
744 275658 : proc->xid = InvalidTransactionId;
745 275658 : proc->vxid.lxid = InvalidLocalTransactionId;
746 275658 : proc->xmin = InvalidTransactionId;
747 :
748 : /* be sure this is cleared in abort */
749 275658 : proc->delayChkptFlags = 0;
750 :
751 : /* must be cleared with xid/xmin: */
752 : /* avoid unnecessarily dirtying shared cachelines */
753 275658 : if (proc->statusFlags & PROC_VACUUM_STATE_MASK)
754 : {
755 1430 : proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;
756 1430 : ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags;
757 : }
758 :
759 : /* Clear the subtransaction-XID cache too while holding the lock */
760 : Assert(ProcGlobal->subxidStates[pgxactoff].count == proc->subxidStatus.count &&
761 : ProcGlobal->subxidStates[pgxactoff].overflowed == proc->subxidStatus.overflowed);
762 275658 : if (proc->subxidStatus.count > 0 || proc->subxidStatus.overflowed)
763 : {
764 1156 : ProcGlobal->subxidStates[pgxactoff].count = 0;
765 1156 : ProcGlobal->subxidStates[pgxactoff].overflowed = false;
766 1156 : proc->subxidStatus.count = 0;
767 1156 : proc->subxidStatus.overflowed = false;
768 : }
769 :
770 : /* Also advance global latestCompletedXid while holding the lock */
771 275658 : MaintainLatestCompletedXid(latestXid);
772 :
773 : /* Same with xactCompletionCount */
774 275658 : TransamVariables->xactCompletionCount++;
775 275658 : }
776 :
777 : /*
778 : * ProcArrayGroupClearXid -- group XID clearing
779 : *
780 : * When we cannot immediately acquire ProcArrayLock in exclusive mode at
781 : * commit time, add ourselves to a list of processes that need their XIDs
782 : * cleared. The first process to add itself to the list will acquire
783 : * ProcArrayLock in exclusive mode and perform ProcArrayEndTransactionInternal
784 : * on behalf of all group members. This avoids a great deal of contention
785 : * around ProcArrayLock when many processes are trying to commit at once,
786 : * since the lock need not be repeatedly handed off from one committing
787 : * process to the next.
788 : */
789 : static void
790 328 : ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
791 : {
792 328 : int pgprocno = GetNumberFromPGProc(proc);
793 328 : PROC_HDR *procglobal = ProcGlobal;
794 : uint32 nextidx;
795 : uint32 wakeidx;
796 :
797 : /* We should definitely have an XID to clear. */
798 : Assert(TransactionIdIsValid(proc->xid));
799 :
800 : /* Add ourselves to the list of processes needing a group XID clear. */
801 328 : proc->procArrayGroupMember = true;
802 328 : proc->procArrayGroupMemberXid = latestXid;
803 328 : nextidx = pg_atomic_read_u32(&procglobal->procArrayGroupFirst);
804 : while (true)
805 : {
806 328 : pg_atomic_write_u32(&proc->procArrayGroupNext, nextidx);
807 :
808 328 : if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst,
809 : &nextidx,
810 : (uint32) pgprocno))
811 328 : break;
812 : }
813 :
814 : /*
815 : * If the list was not empty, the leader will clear our XID. It is
816 : * impossible to have followers without a leader because the first process
817 : * that has added itself to the list will always have nextidx as
818 : * INVALID_PROC_NUMBER.
819 : */
820 328 : if (nextidx != INVALID_PROC_NUMBER)
821 : {
822 30 : int extraWaits = 0;
823 :
824 : /* Sleep until the leader clears our XID. */
825 30 : pgstat_report_wait_start(WAIT_EVENT_PROCARRAY_GROUP_UPDATE);
826 : for (;;)
827 : {
828 : /* acts as a read barrier */
829 30 : PGSemaphoreLock(proc->sem);
830 30 : if (!proc->procArrayGroupMember)
831 30 : break;
832 0 : extraWaits++;
833 : }
834 30 : pgstat_report_wait_end();
835 :
836 : Assert(pg_atomic_read_u32(&proc->procArrayGroupNext) == INVALID_PROC_NUMBER);
837 :
838 : /* Fix semaphore count for any absorbed wakeups */
839 30 : while (extraWaits-- > 0)
840 0 : PGSemaphoreUnlock(proc->sem);
841 30 : return;
842 : }
843 :
844 : /* We are the leader. Acquire the lock on behalf of everyone. */
845 298 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
846 :
847 : /*
848 : * Now that we've got the lock, clear the list of processes waiting for
849 : * group XID clearing, saving a pointer to the head of the list. Trying
850 : * to pop elements one at a time could lead to an ABA problem.
851 : */
852 298 : nextidx = pg_atomic_exchange_u32(&procglobal->procArrayGroupFirst,
853 : INVALID_PROC_NUMBER);
854 :
855 : /* Remember head of list so we can perform wakeups after dropping lock. */
856 298 : wakeidx = nextidx;
857 :
858 : /* Walk the list and clear all XIDs. */
859 626 : while (nextidx != INVALID_PROC_NUMBER)
860 : {
861 328 : PGPROC *nextproc = &allProcs[nextidx];
862 :
863 328 : ProcArrayEndTransactionInternal(nextproc, nextproc->procArrayGroupMemberXid);
864 :
865 : /* Move to next proc in list. */
866 328 : nextidx = pg_atomic_read_u32(&nextproc->procArrayGroupNext);
867 : }
868 :
869 : /* We're done with the lock now. */
870 298 : LWLockRelease(ProcArrayLock);
871 :
872 : /*
873 : * Now that we've released the lock, go back and wake everybody up. We
874 : * don't do this under the lock so as to keep lock hold times to a
875 : * minimum. The system calls we need to perform to wake other processes
876 : * up are probably much slower than the simple memory writes we did while
877 : * holding the lock.
878 : */
879 626 : while (wakeidx != INVALID_PROC_NUMBER)
880 : {
881 328 : PGPROC *nextproc = &allProcs[wakeidx];
882 :
883 328 : wakeidx = pg_atomic_read_u32(&nextproc->procArrayGroupNext);
884 328 : pg_atomic_write_u32(&nextproc->procArrayGroupNext, INVALID_PROC_NUMBER);
885 :
886 : /* ensure all previous writes are visible before follower continues. */
887 328 : pg_write_barrier();
888 :
889 328 : nextproc->procArrayGroupMember = false;
890 :
891 328 : if (nextproc != MyProc)
892 30 : PGSemaphoreUnlock(nextproc->sem);
893 : }
894 : }
895 :
896 : /*
897 : * ProcArrayClearTransaction -- clear the transaction fields
898 : *
899 : * This is used after successfully preparing a 2-phase transaction. We are
900 : * not actually reporting the transaction's XID as no longer running --- it
901 : * will still appear as running because the 2PC's gxact is in the ProcArray
902 : * too. We just have to clear out our own PGPROC.
903 : */
904 : void
905 590 : ProcArrayClearTransaction(PGPROC *proc)
906 : {
907 : int pgxactoff;
908 :
909 : /*
910 : * Currently we need to lock ProcArrayLock exclusively here, as we
911 : * increment xactCompletionCount below. We also need it at least in shared
912 : * mode for pgproc->pgxactoff to stay the same below.
913 : *
914 : * We could however, as this action does not actually change anyone's view
915 : * of the set of running XIDs (our entry is duplicate with the gxact that
916 : * has already been inserted into the ProcArray), lower the lock level to
917 : * shared if we were to make xactCompletionCount an atomic variable. But
918 : * that doesn't seem worth it currently, as a 2PC commit is heavyweight
919 : * enough for this not to be the bottleneck. If it ever becomes a
920 : * bottleneck it may also be worth considering to combine this with the
921 : * subsequent ProcArrayRemove()
922 : */
923 590 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
924 :
925 590 : pgxactoff = proc->pgxactoff;
926 :
927 590 : ProcGlobal->xids[pgxactoff] = InvalidTransactionId;
928 590 : proc->xid = InvalidTransactionId;
929 :
930 590 : proc->vxid.lxid = InvalidLocalTransactionId;
931 590 : proc->xmin = InvalidTransactionId;
932 :
933 : Assert(!(proc->statusFlags & PROC_VACUUM_STATE_MASK));
934 : Assert(!proc->delayChkptFlags);
935 :
936 : /*
937 : * Need to increment completion count even though transaction hasn't
938 : * really committed yet. The reason for that is that GetSnapshotData()
939 : * omits the xid of the current transaction, thus without the increment we
940 : * otherwise could end up reusing the snapshot later. Which would be bad,
941 : * because it might not count the prepared transaction as running.
942 : */
943 590 : TransamVariables->xactCompletionCount++;
944 :
945 : /* Clear the subtransaction-XID cache too */
946 : Assert(ProcGlobal->subxidStates[pgxactoff].count == proc->subxidStatus.count &&
947 : ProcGlobal->subxidStates[pgxactoff].overflowed == proc->subxidStatus.overflowed);
948 590 : if (proc->subxidStatus.count > 0 || proc->subxidStatus.overflowed)
949 : {
950 188 : ProcGlobal->subxidStates[pgxactoff].count = 0;
951 188 : ProcGlobal->subxidStates[pgxactoff].overflowed = false;
952 188 : proc->subxidStatus.count = 0;
953 188 : proc->subxidStatus.overflowed = false;
954 : }
955 :
956 590 : LWLockRelease(ProcArrayLock);
957 590 : }
958 :
959 : /*
960 : * Update TransamVariables->latestCompletedXid to point to latestXid if
961 : * currently older.
962 : */
963 : static void
964 277600 : MaintainLatestCompletedXid(TransactionId latestXid)
965 : {
966 277600 : FullTransactionId cur_latest = TransamVariables->latestCompletedXid;
967 :
968 : Assert(FullTransactionIdIsValid(cur_latest));
969 : Assert(!RecoveryInProgress());
970 : Assert(LWLockHeldByMe(ProcArrayLock));
971 :
972 277600 : if (TransactionIdPrecedes(XidFromFullTransactionId(cur_latest), latestXid))
973 : {
974 250516 : TransamVariables->latestCompletedXid =
975 250516 : FullXidRelativeTo(cur_latest, latestXid);
976 : }
977 :
978 : Assert(IsBootstrapProcessingMode() ||
979 : FullTransactionIdIsNormal(TransamVariables->latestCompletedXid));
980 277600 : }
981 :
982 : /*
983 : * Same as MaintainLatestCompletedXid, except for use during WAL replay.
984 : */
985 : static void
986 46488 : MaintainLatestCompletedXidRecovery(TransactionId latestXid)
987 : {
988 46488 : FullTransactionId cur_latest = TransamVariables->latestCompletedXid;
989 : FullTransactionId rel;
990 :
991 : Assert(AmStartupProcess() || !IsUnderPostmaster);
992 : Assert(LWLockHeldByMe(ProcArrayLock));
993 :
994 : /*
995 : * Need a FullTransactionId to compare latestXid with. Can't rely on
996 : * latestCompletedXid to be initialized in recovery. But in recovery it's
997 : * safe to access nextXid without a lock for the startup process.
998 : */
999 46488 : rel = TransamVariables->nextXid;
1000 : Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
1001 :
1002 92744 : if (!FullTransactionIdIsValid(cur_latest) ||
1003 46256 : TransactionIdPrecedes(XidFromFullTransactionId(cur_latest), latestXid))
1004 : {
1005 34480 : TransamVariables->latestCompletedXid =
1006 34480 : FullXidRelativeTo(rel, latestXid);
1007 : }
1008 :
1009 : Assert(FullTransactionIdIsNormal(TransamVariables->latestCompletedXid));
1010 46488 : }
1011 :
1012 : /*
1013 : * ProcArrayInitRecovery -- initialize recovery xid mgmt environment
1014 : *
1015 : * Remember up to where the startup process initialized the CLOG and subtrans
1016 : * so we can ensure it's initialized gaplessly up to the point where necessary
1017 : * while in recovery.
1018 : */
1019 : void
1020 232 : ProcArrayInitRecovery(TransactionId initializedUptoXID)
1021 : {
1022 : Assert(standbyState == STANDBY_INITIALIZED);
1023 : Assert(TransactionIdIsNormal(initializedUptoXID));
1024 :
1025 : /*
1026 : * we set latestObservedXid to the xid SUBTRANS has been initialized up
1027 : * to, so we can extend it from that point onwards in
1028 : * RecordKnownAssignedTransactionIds, and when we get consistent in
1029 : * ProcArrayApplyRecoveryInfo().
1030 : */
1031 232 : latestObservedXid = initializedUptoXID;
1032 232 : TransactionIdRetreat(latestObservedXid);
1033 232 : }
1034 :
1035 : /*
1036 : * ProcArrayApplyRecoveryInfo -- apply recovery info about xids
1037 : *
1038 : * Takes us through 3 states: Initialized, Pending and Ready.
1039 : * Normal case is to go all the way to Ready straight away, though there
1040 : * are atypical cases where we need to take it in steps.
1041 : *
1042 : * Use the data about running transactions on the primary to create the initial
1043 : * state of KnownAssignedXids. We also use these records to regularly prune
1044 : * KnownAssignedXids because we know it is possible that some transactions
1045 : * with FATAL errors fail to write abort records, which could cause eventual
1046 : * overflow.
1047 : *
1048 : * See comments for LogStandbySnapshot().
1049 : */
1050 : void
1051 1676 : ProcArrayApplyRecoveryInfo(RunningTransactions running)
1052 : {
1053 : TransactionId *xids;
1054 : TransactionId advanceNextXid;
1055 : int nxids;
1056 : int i;
1057 :
1058 : Assert(standbyState >= STANDBY_INITIALIZED);
1059 : Assert(TransactionIdIsValid(running->nextXid));
1060 : Assert(TransactionIdIsValid(running->oldestRunningXid));
1061 : Assert(TransactionIdIsNormal(running->latestCompletedXid));
1062 :
1063 : /*
1064 : * Remove stale transactions, if any.
1065 : */
1066 1676 : ExpireOldKnownAssignedTransactionIds(running->oldestRunningXid);
1067 :
1068 : /*
1069 : * Adjust TransamVariables->nextXid before StandbyReleaseOldLocks(),
1070 : * because we will need it up to date for accessing two-phase transactions
1071 : * in StandbyReleaseOldLocks().
1072 : */
1073 1676 : advanceNextXid = running->nextXid;
1074 1676 : TransactionIdRetreat(advanceNextXid);
1075 1676 : AdvanceNextFullTransactionIdPastXid(advanceNextXid);
1076 : Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
1077 :
1078 : /*
1079 : * Remove stale locks, if any.
1080 : */
1081 1676 : StandbyReleaseOldLocks(running->oldestRunningXid);
1082 :
1083 : /*
1084 : * If our snapshot is already valid, nothing else to do...
1085 : */
1086 1676 : if (standbyState == STANDBY_SNAPSHOT_READY)
1087 1444 : return;
1088 :
1089 : /*
1090 : * If our initial RunningTransactionsData had an overflowed snapshot then
1091 : * we knew we were missing some subxids from our snapshot. If we continue
1092 : * to see overflowed snapshots then we might never be able to start up, so
1093 : * we make another test to see if our snapshot is now valid. We know that
1094 : * the missing subxids are equal to or earlier than nextXid. After we
1095 : * initialise we continue to apply changes during recovery, so once the
1096 : * oldestRunningXid is later than the nextXid from the initial snapshot we
1097 : * know that we no longer have missing information and can mark the
1098 : * snapshot as valid.
1099 : */
1100 232 : if (standbyState == STANDBY_SNAPSHOT_PENDING)
1101 : {
1102 : /*
1103 : * If the snapshot isn't overflowed or if its empty we can reset our
1104 : * pending state and use this snapshot instead.
1105 : */
1106 0 : if (running->subxid_status != SUBXIDS_MISSING || running->xcnt == 0)
1107 : {
1108 : /*
1109 : * If we have already collected known assigned xids, we need to
1110 : * throw them away before we apply the recovery snapshot.
1111 : */
1112 0 : KnownAssignedXidsReset();
1113 0 : standbyState = STANDBY_INITIALIZED;
1114 : }
1115 : else
1116 : {
1117 0 : if (TransactionIdPrecedes(standbySnapshotPendingXmin,
1118 : running->oldestRunningXid))
1119 : {
1120 0 : standbyState = STANDBY_SNAPSHOT_READY;
1121 0 : elog(DEBUG1,
1122 : "recovery snapshots are now enabled");
1123 : }
1124 : else
1125 0 : elog(DEBUG1,
1126 : "recovery snapshot waiting for non-overflowed snapshot or "
1127 : "until oldest active xid on standby is at least %u (now %u)",
1128 : standbySnapshotPendingXmin,
1129 : running->oldestRunningXid);
1130 0 : return;
1131 : }
1132 : }
1133 :
1134 : Assert(standbyState == STANDBY_INITIALIZED);
1135 :
1136 : /*
1137 : * NB: this can be reached at least twice, so make sure new code can deal
1138 : * with that.
1139 : */
1140 :
1141 : /*
1142 : * Nobody else is running yet, but take locks anyhow
1143 : */
1144 232 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1145 :
1146 : /*
1147 : * KnownAssignedXids is sorted so we cannot just add the xids, we have to
1148 : * sort them first.
1149 : *
1150 : * Some of the new xids are top-level xids and some are subtransactions.
1151 : * We don't call SubTransSetParent because it doesn't matter yet. If we
1152 : * aren't overflowed then all xids will fit in snapshot and so we don't
1153 : * need subtrans. If we later overflow, an xid assignment record will add
1154 : * xids to subtrans. If RunningTransactionsData is overflowed then we
1155 : * don't have enough information to correctly update subtrans anyway.
1156 : */
1157 :
1158 : /*
1159 : * Allocate a temporary array to avoid modifying the array passed as
1160 : * argument.
1161 : */
1162 232 : xids = palloc_array(TransactionId, running->xcnt + running->subxcnt);
1163 :
1164 : /*
1165 : * Add to the temp array any xids which have not already completed.
1166 : */
1167 232 : nxids = 0;
1168 240 : for (i = 0; i < running->xcnt + running->subxcnt; i++)
1169 : {
1170 8 : TransactionId xid = running->xids[i];
1171 :
1172 : /*
1173 : * The running-xacts snapshot can contain xids that were still visible
1174 : * in the procarray when the snapshot was taken, but were already
1175 : * WAL-logged as completed. They're not running anymore, so ignore
1176 : * them.
1177 : */
1178 8 : if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
1179 0 : continue;
1180 :
1181 8 : xids[nxids++] = xid;
1182 : }
1183 :
1184 232 : if (nxids > 0)
1185 : {
1186 8 : if (procArray->numKnownAssignedXids != 0)
1187 : {
1188 0 : LWLockRelease(ProcArrayLock);
1189 0 : elog(ERROR, "KnownAssignedXids is not empty");
1190 : }
1191 :
1192 : /*
1193 : * Sort the array so that we can add them safely into
1194 : * KnownAssignedXids.
1195 : *
1196 : * We have to sort them logically, because in KnownAssignedXidsAdd we
1197 : * call TransactionIdFollowsOrEquals and so on. But we know these XIDs
1198 : * come from RUNNING_XACTS, which means there are only normal XIDs
1199 : * from the same epoch, so this is safe.
1200 : */
1201 8 : qsort(xids, nxids, sizeof(TransactionId), xidLogicalComparator);
1202 :
1203 : /*
1204 : * Add the sorted snapshot into KnownAssignedXids. The running-xacts
1205 : * snapshot may include duplicated xids because of prepared
1206 : * transactions, so ignore them.
1207 : */
1208 16 : for (i = 0; i < nxids; i++)
1209 : {
1210 8 : if (i > 0 && TransactionIdEquals(xids[i - 1], xids[i]))
1211 : {
1212 0 : elog(DEBUG1,
1213 : "found duplicated transaction %u for KnownAssignedXids insertion",
1214 : xids[i]);
1215 0 : continue;
1216 : }
1217 8 : KnownAssignedXidsAdd(xids[i], xids[i], true);
1218 : }
1219 :
1220 8 : KnownAssignedXidsDisplay(DEBUG3);
1221 : }
1222 :
1223 232 : pfree(xids);
1224 :
1225 : /*
1226 : * latestObservedXid is at least set to the point where SUBTRANS was
1227 : * started up to (cf. ProcArrayInitRecovery()) or to the biggest xid
1228 : * RecordKnownAssignedTransactionIds() was called for. Initialize
1229 : * subtrans from thereon, up to nextXid - 1.
1230 : *
1231 : * We need to duplicate parts of RecordKnownAssignedTransactionId() here,
1232 : * because we've just added xids to the known assigned xids machinery that
1233 : * haven't gone through RecordKnownAssignedTransactionId().
1234 : */
1235 : Assert(TransactionIdIsNormal(latestObservedXid));
1236 232 : TransactionIdAdvance(latestObservedXid);
1237 464 : while (TransactionIdPrecedes(latestObservedXid, running->nextXid))
1238 : {
1239 0 : ExtendSUBTRANS(latestObservedXid);
1240 0 : TransactionIdAdvance(latestObservedXid);
1241 : }
1242 232 : TransactionIdRetreat(latestObservedXid); /* = running->nextXid - 1 */
1243 :
1244 : /* ----------
1245 : * Now we've got the running xids we need to set the global values that
1246 : * are used to track snapshots as they evolve further.
1247 : *
1248 : * - latestCompletedXid which will be the xmax for snapshots
1249 : * - lastOverflowedXid which shows whether snapshots overflow
1250 : * - nextXid
1251 : *
1252 : * If the snapshot overflowed, then we still initialise with what we know,
1253 : * but the recovery snapshot isn't fully valid yet because we know there
1254 : * are some subxids missing. We don't know the specific subxids that are
1255 : * missing, so conservatively assume the last one is latestObservedXid.
1256 : * ----------
1257 : */
1258 232 : if (running->subxid_status == SUBXIDS_MISSING)
1259 : {
1260 0 : standbyState = STANDBY_SNAPSHOT_PENDING;
1261 :
1262 0 : standbySnapshotPendingXmin = latestObservedXid;
1263 0 : procArray->lastOverflowedXid = latestObservedXid;
1264 : }
1265 : else
1266 : {
1267 232 : standbyState = STANDBY_SNAPSHOT_READY;
1268 :
1269 232 : standbySnapshotPendingXmin = InvalidTransactionId;
1270 :
1271 : /*
1272 : * If the 'xids' array didn't include all subtransactions, we have to
1273 : * mark any snapshots taken as overflowed.
1274 : */
1275 232 : if (running->subxid_status == SUBXIDS_IN_SUBTRANS)
1276 52 : procArray->lastOverflowedXid = latestObservedXid;
1277 : else
1278 : {
1279 : Assert(running->subxid_status == SUBXIDS_IN_ARRAY);
1280 180 : procArray->lastOverflowedXid = InvalidTransactionId;
1281 : }
1282 : }
1283 :
1284 : /*
1285 : * If a transaction wrote a commit record in the gap between taking and
1286 : * logging the snapshot then latestCompletedXid may already be higher than
1287 : * the value from the snapshot, so check before we use the incoming value.
1288 : * It also might not yet be set at all.
1289 : */
1290 232 : MaintainLatestCompletedXidRecovery(running->latestCompletedXid);
1291 :
1292 : /*
1293 : * NB: No need to increment TransamVariables->xactCompletionCount here,
1294 : * nobody can see it yet.
1295 : */
1296 :
1297 232 : LWLockRelease(ProcArrayLock);
1298 :
1299 232 : KnownAssignedXidsDisplay(DEBUG3);
1300 232 : if (standbyState == STANDBY_SNAPSHOT_READY)
1301 232 : elog(DEBUG1, "recovery snapshots are now enabled");
1302 : else
1303 0 : elog(DEBUG1,
1304 : "recovery snapshot waiting for non-overflowed snapshot or "
1305 : "until oldest active xid on standby is at least %u (now %u)",
1306 : standbySnapshotPendingXmin,
1307 : running->oldestRunningXid);
1308 : }
1309 :
1310 : /*
1311 : * ProcArrayApplyXidAssignment
1312 : * Process an XLOG_XACT_ASSIGNMENT WAL record
1313 : */
1314 : void
1315 42 : ProcArrayApplyXidAssignment(TransactionId topxid,
1316 : int nsubxids, TransactionId *subxids)
1317 : {
1318 : TransactionId max_xid;
1319 : int i;
1320 :
1321 : Assert(standbyState >= STANDBY_INITIALIZED);
1322 :
1323 42 : max_xid = TransactionIdLatest(topxid, nsubxids, subxids);
1324 :
1325 : /*
1326 : * Mark all the subtransactions as observed.
1327 : *
1328 : * NOTE: This will fail if the subxid contains too many previously
1329 : * unobserved xids to fit into known-assigned-xids. That shouldn't happen
1330 : * as the code stands, because xid-assignment records should never contain
1331 : * more than PGPROC_MAX_CACHED_SUBXIDS entries.
1332 : */
1333 42 : RecordKnownAssignedTransactionIds(max_xid);
1334 :
1335 : /*
1336 : * Notice that we update pg_subtrans with the top-level xid, rather than
1337 : * the parent xid. This is a difference between normal processing and
1338 : * recovery, yet is still correct in all cases. The reason is that
1339 : * subtransaction commit is not marked in clog until commit processing, so
1340 : * all aborted subtransactions have already been clearly marked in clog.
1341 : * As a result we are able to refer directly to the top-level
1342 : * transaction's state rather than skipping through all the intermediate
1343 : * states in the subtransaction tree. This should be the first time we
1344 : * have attempted to SubTransSetParent().
1345 : */
1346 2730 : for (i = 0; i < nsubxids; i++)
1347 2688 : SubTransSetParent(subxids[i], topxid);
1348 :
1349 : /* KnownAssignedXids isn't maintained yet, so we're done for now */
1350 42 : if (standbyState == STANDBY_INITIALIZED)
1351 0 : return;
1352 :
1353 : /*
1354 : * Uses same locking as transaction commit
1355 : */
1356 42 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1357 :
1358 : /*
1359 : * Remove subxids from known-assigned-xacts.
1360 : */
1361 42 : KnownAssignedXidsRemoveTree(InvalidTransactionId, nsubxids, subxids);
1362 :
1363 : /*
1364 : * Advance lastOverflowedXid to be at least the last of these subxids.
1365 : */
1366 42 : if (TransactionIdPrecedes(procArray->lastOverflowedXid, max_xid))
1367 42 : procArray->lastOverflowedXid = max_xid;
1368 :
1369 42 : LWLockRelease(ProcArrayLock);
1370 : }
1371 :
1372 : /*
1373 : * TransactionIdIsInProgress -- is given transaction running in some backend
1374 : *
1375 : * Aside from some shortcuts such as checking RecentXmin and our own Xid,
1376 : * there are four possibilities for finding a running transaction:
1377 : *
1378 : * 1. The given Xid is a main transaction Id. We will find this out cheaply
1379 : * by looking at ProcGlobal->xids.
1380 : *
1381 : * 2. The given Xid is one of the cached subxact Xids in the PGPROC array.
1382 : * We can find this out cheaply too.
1383 : *
1384 : * 3. In Hot Standby mode, we must search the KnownAssignedXids list to see
1385 : * if the Xid is running on the primary.
1386 : *
1387 : * 4. Search the SubTrans tree to find the Xid's topmost parent, and then see
1388 : * if that is running according to ProcGlobal->xids[] or KnownAssignedXids.
1389 : * This is the slowest way, but sadly it has to be done always if the others
1390 : * failed, unless we see that the cached subxact sets are complete (none have
1391 : * overflowed).
1392 : *
1393 : * ProcArrayLock has to be held while we do 1, 2, 3. If we save the top Xids
1394 : * while doing 1 and 3, we can release the ProcArrayLock while we do 4.
1395 : * This buys back some concurrency (and we can't retrieve the main Xids from
1396 : * ProcGlobal->xids[] again anyway; see GetNewTransactionId).
1397 : */
1398 : bool
1399 22828014 : TransactionIdIsInProgress(TransactionId xid)
1400 : {
1401 : static TransactionId *xids = NULL;
1402 : static TransactionId *other_xids;
1403 : XidCacheStatus *other_subxidstates;
1404 22828014 : int nxids = 0;
1405 22828014 : ProcArrayStruct *arrayP = procArray;
1406 : TransactionId topxid;
1407 : TransactionId latestCompletedXid;
1408 : int mypgxactoff;
1409 : int numProcs;
1410 : int j;
1411 :
1412 : /*
1413 : * Don't bother checking a transaction older than RecentXmin; it could not
1414 : * possibly still be running. (Note: in particular, this guarantees that
1415 : * we reject InvalidTransactionId, FrozenTransactionId, etc as not
1416 : * running.)
1417 : */
1418 22828014 : if (TransactionIdPrecedes(xid, RecentXmin))
1419 : {
1420 : xc_by_recent_xmin_inc();
1421 9468566 : return false;
1422 : }
1423 :
1424 : /*
1425 : * We may have just checked the status of this transaction, so if it is
1426 : * already known to be completed, we can fall out without any access to
1427 : * shared memory.
1428 : */
1429 13359448 : if (TransactionIdEquals(cachedXidIsNotInProgress, xid))
1430 : {
1431 : xc_by_known_xact_inc();
1432 1755996 : return false;
1433 : }
1434 :
1435 : /*
1436 : * Also, we can handle our own transaction (and subtransactions) without
1437 : * any access to shared memory.
1438 : */
1439 11603452 : if (TransactionIdIsCurrentTransactionId(xid))
1440 : {
1441 : xc_by_my_xact_inc();
1442 402440 : return true;
1443 : }
1444 :
1445 : /*
1446 : * If first time through, get workspace to remember main XIDs in. We
1447 : * malloc it permanently to avoid repeated palloc/pfree overhead.
1448 : */
1449 11201012 : if (xids == NULL)
1450 : {
1451 : /*
1452 : * In hot standby mode, reserve enough space to hold all xids in the
1453 : * known-assigned list. If we later finish recovery, we no longer need
1454 : * the bigger array, but we don't bother to shrink it.
1455 : */
1456 2634 : int maxxids = RecoveryInProgress() ? TOTAL_MAX_CACHED_SUBXIDS : arrayP->maxProcs;
1457 :
1458 2634 : xids = (TransactionId *) malloc(maxxids * sizeof(TransactionId));
1459 2634 : if (xids == NULL)
1460 0 : ereport(ERROR,
1461 : (errcode(ERRCODE_OUT_OF_MEMORY),
1462 : errmsg("out of memory")));
1463 : }
1464 :
1465 11201012 : other_xids = ProcGlobal->xids;
1466 11201012 : other_subxidstates = ProcGlobal->subxidStates;
1467 :
1468 11201012 : LWLockAcquire(ProcArrayLock, LW_SHARED);
1469 :
1470 : /*
1471 : * Now that we have the lock, we can check latestCompletedXid; if the
1472 : * target Xid is after that, it's surely still running.
1473 : */
1474 11201012 : latestCompletedXid =
1475 11201012 : XidFromFullTransactionId(TransamVariables->latestCompletedXid);
1476 11201012 : if (TransactionIdPrecedes(latestCompletedXid, xid))
1477 : {
1478 3077754 : LWLockRelease(ProcArrayLock);
1479 : xc_by_latest_xid_inc();
1480 3077754 : return true;
1481 : }
1482 :
1483 : /* No shortcuts, gotta grovel through the array */
1484 8123258 : mypgxactoff = MyProc->pgxactoff;
1485 8123258 : numProcs = arrayP->numProcs;
1486 8471628 : for (int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)
1487 : {
1488 : int pgprocno;
1489 : PGPROC *proc;
1490 : TransactionId pxid;
1491 : int pxids;
1492 :
1493 : /* Ignore ourselves --- dealt with it above */
1494 8442280 : if (pgxactoff == mypgxactoff)
1495 31864 : continue;
1496 :
1497 : /* Fetch xid just once - see GetNewTransactionId */
1498 8410416 : pxid = UINT32_ACCESS_ONCE(other_xids[pgxactoff]);
1499 :
1500 8410416 : if (!TransactionIdIsValid(pxid))
1501 216196 : continue;
1502 :
1503 : /*
1504 : * Step 1: check the main Xid
1505 : */
1506 8194220 : if (TransactionIdEquals(pxid, xid))
1507 : {
1508 8093116 : LWLockRelease(ProcArrayLock);
1509 : xc_by_main_xid_inc();
1510 8093116 : return true;
1511 : }
1512 :
1513 : /*
1514 : * We can ignore main Xids that are younger than the target Xid, since
1515 : * the target could not possibly be their child.
1516 : */
1517 101104 : if (TransactionIdPrecedes(xid, pxid))
1518 51752 : continue;
1519 :
1520 : /*
1521 : * Step 2: check the cached child-Xids arrays
1522 : */
1523 49352 : pxids = other_subxidstates[pgxactoff].count;
1524 49352 : pg_read_barrier(); /* pairs with barrier in GetNewTransactionId() */
1525 49352 : pgprocno = arrayP->pgprocnos[pgxactoff];
1526 49352 : proc = &allProcs[pgprocno];
1527 152934 : for (j = pxids - 1; j >= 0; j--)
1528 : {
1529 : /* Fetch xid just once - see GetNewTransactionId */
1530 104376 : TransactionId cxid = UINT32_ACCESS_ONCE(proc->subxids.xids[j]);
1531 :
1532 104376 : if (TransactionIdEquals(cxid, xid))
1533 : {
1534 794 : LWLockRelease(ProcArrayLock);
1535 : xc_by_child_xid_inc();
1536 794 : return true;
1537 : }
1538 : }
1539 :
1540 : /*
1541 : * Save the main Xid for step 4. We only need to remember main Xids
1542 : * that have uncached children. (Note: there is no race condition
1543 : * here because the overflowed flag cannot be cleared, only set, while
1544 : * we hold ProcArrayLock. So we can't miss an Xid that we need to
1545 : * worry about.)
1546 : */
1547 48558 : if (other_subxidstates[pgxactoff].overflowed)
1548 504 : xids[nxids++] = pxid;
1549 : }
1550 :
1551 : /*
1552 : * Step 3: in hot standby mode, check the known-assigned-xids list. XIDs
1553 : * in the list must be treated as running.
1554 : */
1555 29348 : if (RecoveryInProgress())
1556 : {
1557 : /* none of the PGPROC entries should have XIDs in hot standby mode */
1558 : Assert(nxids == 0);
1559 :
1560 2 : if (KnownAssignedXidExists(xid))
1561 : {
1562 0 : LWLockRelease(ProcArrayLock);
1563 : xc_by_known_assigned_inc();
1564 0 : return true;
1565 : }
1566 :
1567 : /*
1568 : * If the KnownAssignedXids overflowed, we have to check pg_subtrans
1569 : * too. Fetch all xids from KnownAssignedXids that are lower than
1570 : * xid, since if xid is a subtransaction its parent will always have a
1571 : * lower value. Note we will collect both main and subXIDs here, but
1572 : * there's no help for it.
1573 : */
1574 2 : if (TransactionIdPrecedesOrEquals(xid, procArray->lastOverflowedXid))
1575 0 : nxids = KnownAssignedXidsGet(xids, xid);
1576 : }
1577 :
1578 29348 : LWLockRelease(ProcArrayLock);
1579 :
1580 : /*
1581 : * If none of the relevant caches overflowed, we know the Xid is not
1582 : * running without even looking at pg_subtrans.
1583 : */
1584 29348 : if (nxids == 0)
1585 : {
1586 : xc_no_overflow_inc();
1587 28844 : cachedXidIsNotInProgress = xid;
1588 28844 : return false;
1589 : }
1590 :
1591 : /*
1592 : * Step 4: have to check pg_subtrans.
1593 : *
1594 : * At this point, we know it's either a subtransaction of one of the Xids
1595 : * in xids[], or it's not running. If it's an already-failed
1596 : * subtransaction, we want to say "not running" even though its parent may
1597 : * still be running. So first, check pg_xact to see if it's been aborted.
1598 : */
1599 : xc_slow_answer_inc();
1600 :
1601 504 : if (TransactionIdDidAbort(xid))
1602 : {
1603 0 : cachedXidIsNotInProgress = xid;
1604 0 : return false;
1605 : }
1606 :
1607 : /*
1608 : * It isn't aborted, so check whether the transaction tree it belongs to
1609 : * is still running (or, more precisely, whether it was running when we
1610 : * held ProcArrayLock).
1611 : */
1612 504 : topxid = SubTransGetTopmostTransaction(xid);
1613 : Assert(TransactionIdIsValid(topxid));
1614 818 : if (!TransactionIdEquals(topxid, xid) &&
1615 314 : pg_lfind32(topxid, xids, nxids))
1616 314 : return true;
1617 :
1618 190 : cachedXidIsNotInProgress = xid;
1619 190 : return false;
1620 : }
1621 :
1622 :
1623 : /*
1624 : * Determine XID horizons.
1625 : *
1626 : * This is used by wrapper functions like GetOldestNonRemovableTransactionId()
1627 : * (for VACUUM), GetReplicationHorizons() (for hot_standby_feedback), etc as
1628 : * well as "internally" by GlobalVisUpdate() (see comment above struct
1629 : * GlobalVisState).
1630 : *
1631 : * See the definition of ComputeXidHorizonsResult for the various computed
1632 : * horizons.
1633 : *
1634 : * For VACUUM separate horizons (used to decide which deleted tuples must
1635 : * be preserved), for shared and non-shared tables are computed. For shared
1636 : * relations backends in all databases must be considered, but for non-shared
1637 : * relations that's not required, since only backends in my own database could
1638 : * ever see the tuples in them. Also, we can ignore concurrently running lazy
1639 : * VACUUMs because (a) they must be working on other tables, and (b) they
1640 : * don't need to do snapshot-based lookups.
1641 : *
1642 : * This also computes a horizon used to truncate pg_subtrans. For that
1643 : * backends in all databases have to be considered, and concurrently running
1644 : * lazy VACUUMs cannot be ignored, as they still may perform pg_subtrans
1645 : * accesses.
1646 : *
1647 : * Note: we include all currently running xids in the set of considered xids.
1648 : * This ensures that if a just-started xact has not yet set its snapshot,
1649 : * when it does set the snapshot it cannot set xmin less than what we compute.
1650 : * See notes in src/backend/access/transam/README.
1651 : *
1652 : * Note: despite the above, it's possible for the calculated values to move
1653 : * backwards on repeated calls. The calculated values are conservative, so
1654 : * that anything older is definitely not considered as running by anyone
1655 : * anymore, but the exact values calculated depend on a number of things. For
1656 : * example, if there are no transactions running in the current database, the
1657 : * horizon for normal tables will be latestCompletedXid. If a transaction
1658 : * begins after that, its xmin will include in-progress transactions in other
1659 : * databases that started earlier, so another call will return a lower value.
1660 : * Nonetheless it is safe to vacuum a table in the current database with the
1661 : * first result. There are also replication-related effects: a walsender
1662 : * process can set its xmin based on transactions that are no longer running
1663 : * on the primary but are still being replayed on the standby, thus possibly
1664 : * making the values go backwards. In this case there is a possibility that
1665 : * we lose data that the standby would like to have, but unless the standby
1666 : * uses a replication slot to make its xmin persistent there is little we can
1667 : * do about that --- data is only protected if the walsender runs continuously
1668 : * while queries are executed on the standby. (The Hot Standby code deals
1669 : * with such cases by failing standby queries that needed to access
1670 : * already-removed data, so there's no integrity bug.)
1671 : *
1672 : * Note: the approximate horizons (see definition of GlobalVisState) are
1673 : * updated by the computations done here. That's currently required for
1674 : * correctness and a small optimization. Without doing so it's possible that
1675 : * heap vacuum's call to heap_page_prune_and_freeze() uses a more conservative
1676 : * horizon than later when deciding which tuples can be removed - which the
1677 : * code doesn't expect (breaking HOT).
1678 : */
1679 : static void
1680 360360 : ComputeXidHorizons(ComputeXidHorizonsResult *h)
1681 : {
1682 360360 : ProcArrayStruct *arrayP = procArray;
1683 : TransactionId kaxmin;
1684 360360 : bool in_recovery = RecoveryInProgress();
1685 360360 : TransactionId *other_xids = ProcGlobal->xids;
1686 :
1687 : /* inferred after ProcArrayLock is released */
1688 360360 : h->catalog_oldest_nonremovable = InvalidTransactionId;
1689 :
1690 360360 : LWLockAcquire(ProcArrayLock, LW_SHARED);
1691 :
1692 360360 : h->latest_completed = TransamVariables->latestCompletedXid;
1693 :
1694 : /*
1695 : * We initialize the MIN() calculation with latestCompletedXid + 1. This
1696 : * is a lower bound for the XIDs that might appear in the ProcArray later,
1697 : * and so protects us against overestimating the result due to future
1698 : * additions.
1699 : */
1700 : {
1701 : TransactionId initial;
1702 :
1703 360360 : initial = XidFromFullTransactionId(h->latest_completed);
1704 : Assert(TransactionIdIsValid(initial));
1705 360360 : TransactionIdAdvance(initial);
1706 :
1707 360360 : h->oldest_considered_running = initial;
1708 360360 : h->shared_oldest_nonremovable = initial;
1709 360360 : h->data_oldest_nonremovable = initial;
1710 :
1711 : /*
1712 : * Only modifications made by this backend affect the horizon for
1713 : * temporary relations. Instead of a check in each iteration of the
1714 : * loop over all PGPROCs it is cheaper to just initialize to the
1715 : * current top-level xid any.
1716 : *
1717 : * Without an assigned xid we could use a horizon as aggressive as
1718 : * GetNewTransactionId(), but we can get away with the much cheaper
1719 : * latestCompletedXid + 1: If this backend has no xid there, by
1720 : * definition, can't be any newer changes in the temp table than
1721 : * latestCompletedXid.
1722 : */
1723 360360 : if (TransactionIdIsValid(MyProc->xid))
1724 66424 : h->temp_oldest_nonremovable = MyProc->xid;
1725 : else
1726 293936 : h->temp_oldest_nonremovable = initial;
1727 : }
1728 :
1729 : /*
1730 : * Fetch slot horizons while ProcArrayLock is held - the
1731 : * LWLockAcquire/LWLockRelease are a barrier, ensuring this happens inside
1732 : * the lock.
1733 : */
1734 360360 : h->slot_xmin = procArray->replication_slot_xmin;
1735 360360 : h->slot_catalog_xmin = procArray->replication_slot_catalog_xmin;
1736 :
1737 2213764 : for (int index = 0; index < arrayP->numProcs; index++)
1738 : {
1739 1853404 : int pgprocno = arrayP->pgprocnos[index];
1740 1853404 : PGPROC *proc = &allProcs[pgprocno];
1741 1853404 : int8 statusFlags = ProcGlobal->statusFlags[index];
1742 : TransactionId xid;
1743 : TransactionId xmin;
1744 :
1745 : /* Fetch xid just once - see GetNewTransactionId */
1746 1853404 : xid = UINT32_ACCESS_ONCE(other_xids[index]);
1747 1853404 : xmin = UINT32_ACCESS_ONCE(proc->xmin);
1748 :
1749 : /*
1750 : * Consider both the transaction's Xmin, and its Xid.
1751 : *
1752 : * We must check both because a transaction might have an Xmin but not
1753 : * (yet) an Xid; conversely, if it has an Xid, that could determine
1754 : * some not-yet-set Xmin.
1755 : */
1756 1853404 : xmin = TransactionIdOlder(xmin, xid);
1757 :
1758 : /* if neither is set, this proc doesn't influence the horizon */
1759 1853404 : if (!TransactionIdIsValid(xmin))
1760 810822 : continue;
1761 :
1762 : /*
1763 : * Don't ignore any procs when determining which transactions might be
1764 : * considered running. While slots should ensure logical decoding
1765 : * backends are protected even without this check, it can't hurt to
1766 : * include them here as well..
1767 : */
1768 1042582 : h->oldest_considered_running =
1769 1042582 : TransactionIdOlder(h->oldest_considered_running, xmin);
1770 :
1771 : /*
1772 : * Skip over backends either vacuuming (which is ok with rows being
1773 : * removed, as long as pg_subtrans is not truncated) or doing logical
1774 : * decoding (which manages xmin separately, check below).
1775 : */
1776 1042582 : if (statusFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING))
1777 339782 : continue;
1778 :
1779 : /* shared tables need to take backends in all databases into account */
1780 702800 : h->shared_oldest_nonremovable =
1781 702800 : TransactionIdOlder(h->shared_oldest_nonremovable, xmin);
1782 :
1783 : /*
1784 : * Normally sessions in other databases are ignored for anything but
1785 : * the shared horizon.
1786 : *
1787 : * However, include them when MyDatabaseId is not (yet) set. A
1788 : * backend in the process of starting up must not compute a "too
1789 : * aggressive" horizon, otherwise we could end up using it to prune
1790 : * still-needed data away. If the current backend never connects to a
1791 : * database this is harmless, because data_oldest_nonremovable will
1792 : * never be utilized.
1793 : *
1794 : * Also, sessions marked with PROC_AFFECTS_ALL_HORIZONS should always
1795 : * be included. (This flag is used for hot standby feedback, which
1796 : * can't be tied to a specific database.)
1797 : *
1798 : * Also, while in recovery we cannot compute an accurate per-database
1799 : * horizon, as all xids are managed via the KnownAssignedXids
1800 : * machinery.
1801 : */
1802 702800 : if (proc->databaseId == MyDatabaseId ||
1803 38782 : MyDatabaseId == InvalidOid ||
1804 24150 : (statusFlags & PROC_AFFECTS_ALL_HORIZONS) ||
1805 : in_recovery)
1806 : {
1807 678654 : h->data_oldest_nonremovable =
1808 678654 : TransactionIdOlder(h->data_oldest_nonremovable, xmin);
1809 : }
1810 : }
1811 :
1812 : /*
1813 : * If in recovery fetch oldest xid in KnownAssignedXids, will be applied
1814 : * after lock is released.
1815 : */
1816 360360 : if (in_recovery)
1817 700 : kaxmin = KnownAssignedXidsGetOldestXmin();
1818 :
1819 : /*
1820 : * No other information from shared state is needed, release the lock
1821 : * immediately. The rest of the computations can be done without a lock.
1822 : */
1823 360360 : LWLockRelease(ProcArrayLock);
1824 :
1825 360360 : if (in_recovery)
1826 : {
1827 700 : h->oldest_considered_running =
1828 700 : TransactionIdOlder(h->oldest_considered_running, kaxmin);
1829 700 : h->shared_oldest_nonremovable =
1830 700 : TransactionIdOlder(h->shared_oldest_nonremovable, kaxmin);
1831 700 : h->data_oldest_nonremovable =
1832 700 : TransactionIdOlder(h->data_oldest_nonremovable, kaxmin);
1833 : /* temp relations cannot be accessed in recovery */
1834 : }
1835 :
1836 : Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1837 : h->shared_oldest_nonremovable));
1838 : Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1839 : h->data_oldest_nonremovable));
1840 :
1841 : /*
1842 : * Check whether there are replication slots requiring an older xmin.
1843 : */
1844 360360 : h->shared_oldest_nonremovable =
1845 360360 : TransactionIdOlder(h->shared_oldest_nonremovable, h->slot_xmin);
1846 360360 : h->data_oldest_nonremovable =
1847 360360 : TransactionIdOlder(h->data_oldest_nonremovable, h->slot_xmin);
1848 :
1849 : /*
1850 : * The only difference between catalog / data horizons is that the slot's
1851 : * catalog xmin is applied to the catalog one (so catalogs can be accessed
1852 : * for logical decoding). Initialize with data horizon, and then back up
1853 : * further if necessary. Have to back up the shared horizon as well, since
1854 : * that also can contain catalogs.
1855 : */
1856 360360 : h->shared_oldest_nonremovable_raw = h->shared_oldest_nonremovable;
1857 360360 : h->shared_oldest_nonremovable =
1858 360360 : TransactionIdOlder(h->shared_oldest_nonremovable,
1859 : h->slot_catalog_xmin);
1860 360360 : h->catalog_oldest_nonremovable = h->data_oldest_nonremovable;
1861 360360 : h->catalog_oldest_nonremovable =
1862 360360 : TransactionIdOlder(h->catalog_oldest_nonremovable,
1863 : h->slot_catalog_xmin);
1864 :
1865 : /*
1866 : * It's possible that slots backed up the horizons further than
1867 : * oldest_considered_running. Fix.
1868 : */
1869 360360 : h->oldest_considered_running =
1870 360360 : TransactionIdOlder(h->oldest_considered_running,
1871 : h->shared_oldest_nonremovable);
1872 360360 : h->oldest_considered_running =
1873 360360 : TransactionIdOlder(h->oldest_considered_running,
1874 : h->catalog_oldest_nonremovable);
1875 360360 : h->oldest_considered_running =
1876 360360 : TransactionIdOlder(h->oldest_considered_running,
1877 : h->data_oldest_nonremovable);
1878 :
1879 : /*
1880 : * shared horizons have to be at least as old as the oldest visible in
1881 : * current db
1882 : */
1883 : Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1884 : h->data_oldest_nonremovable));
1885 : Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1886 : h->catalog_oldest_nonremovable));
1887 :
1888 : /*
1889 : * Horizons need to ensure that pg_subtrans access is still possible for
1890 : * the relevant backends.
1891 : */
1892 : Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1893 : h->shared_oldest_nonremovable));
1894 : Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1895 : h->catalog_oldest_nonremovable));
1896 : Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1897 : h->data_oldest_nonremovable));
1898 : Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1899 : h->temp_oldest_nonremovable));
1900 : Assert(!TransactionIdIsValid(h->slot_xmin) ||
1901 : TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1902 : h->slot_xmin));
1903 : Assert(!TransactionIdIsValid(h->slot_catalog_xmin) ||
1904 : TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1905 : h->slot_catalog_xmin));
1906 :
1907 : /* update approximate horizons with the computed horizons */
1908 360360 : GlobalVisUpdateApply(h);
1909 360360 : }
1910 :
1911 : /*
1912 : * Determine what kind of visibility horizon needs to be used for a
1913 : * relation. If rel is NULL, the most conservative horizon is used.
1914 : */
1915 : static inline GlobalVisHorizonKind
1916 29048872 : GlobalVisHorizonKindForRel(Relation rel)
1917 : {
1918 : /*
1919 : * Other relkinds currently don't contain xids, nor always the necessary
1920 : * logical decoding markers.
1921 : */
1922 : Assert(!rel ||
1923 : rel->rd_rel->relkind == RELKIND_RELATION ||
1924 : rel->rd_rel->relkind == RELKIND_MATVIEW ||
1925 : rel->rd_rel->relkind == RELKIND_TOASTVALUE);
1926 :
1927 29048872 : if (rel == NULL || rel->rd_rel->relisshared || RecoveryInProgress())
1928 207710 : return VISHORIZON_SHARED;
1929 28841162 : else if (IsCatalogRelation(rel) ||
1930 22777452 : RelationIsAccessibleInLogicalDecoding(rel))
1931 6063718 : return VISHORIZON_CATALOG;
1932 22777444 : else if (!RELATION_IS_LOCAL(rel))
1933 22668274 : return VISHORIZON_DATA;
1934 : else
1935 109170 : return VISHORIZON_TEMP;
1936 : }
1937 :
1938 : /*
1939 : * Return the oldest XID for which deleted tuples must be preserved in the
1940 : * passed table.
1941 : *
1942 : * If rel is not NULL the horizon may be considerably more recent than
1943 : * otherwise (i.e. fewer tuples will be removable). In the NULL case a horizon
1944 : * that is correct (but not optimal) for all relations will be returned.
1945 : *
1946 : * This is used by VACUUM to decide which deleted tuples must be preserved in
1947 : * the passed in table.
1948 : */
1949 : TransactionId
1950 250522 : GetOldestNonRemovableTransactionId(Relation rel)
1951 : {
1952 : ComputeXidHorizonsResult horizons;
1953 :
1954 250522 : ComputeXidHorizons(&horizons);
1955 :
1956 250522 : switch (GlobalVisHorizonKindForRel(rel))
1957 : {
1958 37574 : case VISHORIZON_SHARED:
1959 37574 : return horizons.shared_oldest_nonremovable;
1960 148094 : case VISHORIZON_CATALOG:
1961 148094 : return horizons.catalog_oldest_nonremovable;
1962 39604 : case VISHORIZON_DATA:
1963 39604 : return horizons.data_oldest_nonremovable;
1964 25250 : case VISHORIZON_TEMP:
1965 25250 : return horizons.temp_oldest_nonremovable;
1966 : }
1967 :
1968 : /* just to prevent compiler warnings */
1969 0 : return InvalidTransactionId;
1970 : }
1971 :
1972 : /*
1973 : * Return the oldest transaction id any currently running backend might still
1974 : * consider running. This should not be used for visibility / pruning
1975 : * determinations (see GetOldestNonRemovableTransactionId()), but for
1976 : * decisions like up to where pg_subtrans can be truncated.
1977 : */
1978 : TransactionId
1979 3512 : GetOldestTransactionIdConsideredRunning(void)
1980 : {
1981 : ComputeXidHorizonsResult horizons;
1982 :
1983 3512 : ComputeXidHorizons(&horizons);
1984 :
1985 3512 : return horizons.oldest_considered_running;
1986 : }
1987 :
1988 : /*
1989 : * Return the visibility horizons for a hot standby feedback message.
1990 : */
1991 : void
1992 110 : GetReplicationHorizons(TransactionId *xmin, TransactionId *catalog_xmin)
1993 : {
1994 : ComputeXidHorizonsResult horizons;
1995 :
1996 110 : ComputeXidHorizons(&horizons);
1997 :
1998 : /*
1999 : * Don't want to use shared_oldest_nonremovable here, as that contains the
2000 : * effect of replication slot's catalog_xmin. We want to send a separate
2001 : * feedback for the catalog horizon, so the primary can remove data table
2002 : * contents more aggressively.
2003 : */
2004 110 : *xmin = horizons.shared_oldest_nonremovable_raw;
2005 110 : *catalog_xmin = horizons.slot_catalog_xmin;
2006 110 : }
2007 :
2008 : /*
2009 : * GetMaxSnapshotXidCount -- get max size for snapshot XID array
2010 : *
2011 : * We have to export this for use by snapmgr.c.
2012 : */
2013 : int
2014 69148 : GetMaxSnapshotXidCount(void)
2015 : {
2016 69148 : return procArray->maxProcs;
2017 : }
2018 :
2019 : /*
2020 : * GetMaxSnapshotSubxidCount -- get max size for snapshot sub-XID array
2021 : *
2022 : * We have to export this for use by snapmgr.c.
2023 : */
2024 : int
2025 68766 : GetMaxSnapshotSubxidCount(void)
2026 : {
2027 68766 : return TOTAL_MAX_CACHED_SUBXIDS;
2028 : }
2029 :
2030 : /*
2031 : * Helper function for GetSnapshotData() that checks if the bulk of the
2032 : * visibility information in the snapshot is still valid. If so, it updates
2033 : * the fields that need to change and returns true. Otherwise it returns
2034 : * false.
2035 : *
2036 : * This very likely can be evolved to not need ProcArrayLock held (at very
2037 : * least in the case we already hold a snapshot), but that's for another day.
2038 : */
2039 : static bool
2040 4272952 : GetSnapshotDataReuse(Snapshot snapshot)
2041 : {
2042 : uint64 curXactCompletionCount;
2043 :
2044 : Assert(LWLockHeldByMe(ProcArrayLock));
2045 :
2046 4272952 : if (unlikely(snapshot->snapXactCompletionCount == 0))
2047 68728 : return false;
2048 :
2049 4204224 : curXactCompletionCount = TransamVariables->xactCompletionCount;
2050 4204224 : if (curXactCompletionCount != snapshot->snapXactCompletionCount)
2051 726594 : return false;
2052 :
2053 : /*
2054 : * If the current xactCompletionCount is still the same as it was at the
2055 : * time the snapshot was built, we can be sure that rebuilding the
2056 : * contents of the snapshot the hard way would result in the same snapshot
2057 : * contents:
2058 : *
2059 : * As explained in transam/README, the set of xids considered running by
2060 : * GetSnapshotData() cannot change while ProcArrayLock is held. Snapshot
2061 : * contents only depend on transactions with xids and xactCompletionCount
2062 : * is incremented whenever a transaction with an xid finishes (while
2063 : * holding ProcArrayLock exclusively). Thus the xactCompletionCount check
2064 : * ensures we would detect if the snapshot would have changed.
2065 : *
2066 : * As the snapshot contents are the same as it was before, it is safe to
2067 : * re-enter the snapshot's xmin into the PGPROC array. None of the rows
2068 : * visible under the snapshot could already have been removed (that'd
2069 : * require the set of running transactions to change) and it fulfills the
2070 : * requirement that concurrent GetSnapshotData() calls yield the same
2071 : * xmin.
2072 : */
2073 3477630 : if (!TransactionIdIsValid(MyProc->xmin))
2074 1309046 : MyProc->xmin = TransactionXmin = snapshot->xmin;
2075 :
2076 3477630 : RecentXmin = snapshot->xmin;
2077 : Assert(TransactionIdPrecedesOrEquals(TransactionXmin, RecentXmin));
2078 :
2079 3477630 : snapshot->curcid = GetCurrentCommandId(false);
2080 3477630 : snapshot->active_count = 0;
2081 3477630 : snapshot->regd_count = 0;
2082 3477630 : snapshot->copied = false;
2083 :
2084 3477630 : return true;
2085 : }
2086 :
2087 : /*
2088 : * GetSnapshotData -- returns information about running transactions.
2089 : *
2090 : * The returned snapshot includes xmin (lowest still-running xact ID),
2091 : * xmax (highest completed xact ID + 1), and a list of running xact IDs
2092 : * in the range xmin <= xid < xmax. It is used as follows:
2093 : * All xact IDs < xmin are considered finished.
2094 : * All xact IDs >= xmax are considered still running.
2095 : * For an xact ID xmin <= xid < xmax, consult list to see whether
2096 : * it is considered running or not.
2097 : * This ensures that the set of transactions seen as "running" by the
2098 : * current xact will not change after it takes the snapshot.
2099 : *
2100 : * All running top-level XIDs are included in the snapshot, except for lazy
2101 : * VACUUM processes. We also try to include running subtransaction XIDs,
2102 : * but since PGPROC has only a limited cache area for subxact XIDs, full
2103 : * information may not be available. If we find any overflowed subxid arrays,
2104 : * we have to mark the snapshot's subxid data as overflowed, and extra work
2105 : * *may* need to be done to determine what's running (see XidInMVCCSnapshot()).
2106 : *
2107 : * We also update the following backend-global variables:
2108 : * TransactionXmin: the oldest xmin of any snapshot in use in the
2109 : * current transaction (this is the same as MyProc->xmin).
2110 : * RecentXmin: the xmin computed for the most recent snapshot. XIDs
2111 : * older than this are known not running any more.
2112 : *
2113 : * And try to advance the bounds of GlobalVis{Shared,Catalog,Data,Temp}Rels
2114 : * for the benefit of the GlobalVisTest* family of functions.
2115 : *
2116 : * Note: this function should probably not be called with an argument that's
2117 : * not statically allocated (see xip allocation below).
2118 : */
2119 : Snapshot
2120 4272952 : GetSnapshotData(Snapshot snapshot)
2121 : {
2122 4272952 : ProcArrayStruct *arrayP = procArray;
2123 4272952 : TransactionId *other_xids = ProcGlobal->xids;
2124 : TransactionId xmin;
2125 : TransactionId xmax;
2126 4272952 : int count = 0;
2127 4272952 : int subcount = 0;
2128 4272952 : bool suboverflowed = false;
2129 : FullTransactionId latest_completed;
2130 : TransactionId oldestxid;
2131 : int mypgxactoff;
2132 : TransactionId myxid;
2133 : uint64 curXactCompletionCount;
2134 :
2135 4272952 : TransactionId replication_slot_xmin = InvalidTransactionId;
2136 4272952 : TransactionId replication_slot_catalog_xmin = InvalidTransactionId;
2137 :
2138 : Assert(snapshot != NULL);
2139 :
2140 : /*
2141 : * Allocating space for maxProcs xids is usually overkill; numProcs would
2142 : * be sufficient. But it seems better to do the malloc while not holding
2143 : * the lock, so we can't look at numProcs. Likewise, we allocate much
2144 : * more subxip storage than is probably needed.
2145 : *
2146 : * This does open a possibility for avoiding repeated malloc/free: since
2147 : * maxProcs does not change at runtime, we can simply reuse the previous
2148 : * xip arrays if any. (This relies on the fact that all callers pass
2149 : * static SnapshotData structs.)
2150 : */
2151 4272952 : if (snapshot->xip == NULL)
2152 : {
2153 : /*
2154 : * First call for this snapshot. Snapshot is same size whether or not
2155 : * we are in recovery, see later comments.
2156 : */
2157 68716 : snapshot->xip = (TransactionId *)
2158 68716 : malloc(GetMaxSnapshotXidCount() * sizeof(TransactionId));
2159 68716 : if (snapshot->xip == NULL)
2160 0 : ereport(ERROR,
2161 : (errcode(ERRCODE_OUT_OF_MEMORY),
2162 : errmsg("out of memory")));
2163 : Assert(snapshot->subxip == NULL);
2164 68716 : snapshot->subxip = (TransactionId *)
2165 68716 : malloc(GetMaxSnapshotSubxidCount() * sizeof(TransactionId));
2166 68716 : if (snapshot->subxip == NULL)
2167 0 : ereport(ERROR,
2168 : (errcode(ERRCODE_OUT_OF_MEMORY),
2169 : errmsg("out of memory")));
2170 : }
2171 :
2172 : /*
2173 : * It is sufficient to get shared lock on ProcArrayLock, even if we are
2174 : * going to set MyProc->xmin.
2175 : */
2176 4272952 : LWLockAcquire(ProcArrayLock, LW_SHARED);
2177 :
2178 4272952 : if (GetSnapshotDataReuse(snapshot))
2179 : {
2180 3477630 : LWLockRelease(ProcArrayLock);
2181 3477630 : return snapshot;
2182 : }
2183 :
2184 795322 : latest_completed = TransamVariables->latestCompletedXid;
2185 795322 : mypgxactoff = MyProc->pgxactoff;
2186 795322 : myxid = other_xids[mypgxactoff];
2187 : Assert(myxid == MyProc->xid);
2188 :
2189 795322 : oldestxid = TransamVariables->oldestXid;
2190 795322 : curXactCompletionCount = TransamVariables->xactCompletionCount;
2191 :
2192 : /* xmax is always latestCompletedXid + 1 */
2193 795322 : xmax = XidFromFullTransactionId(latest_completed);
2194 795322 : TransactionIdAdvance(xmax);
2195 : Assert(TransactionIdIsNormal(xmax));
2196 :
2197 : /* initialize xmin calculation with xmax */
2198 795322 : xmin = xmax;
2199 :
2200 : /* take own xid into account, saves a check inside the loop */
2201 795322 : if (TransactionIdIsNormal(myxid) && NormalTransactionIdPrecedes(myxid, xmin))
2202 55722 : xmin = myxid;
2203 :
2204 795322 : snapshot->takenDuringRecovery = RecoveryInProgress();
2205 :
2206 795322 : if (!snapshot->takenDuringRecovery)
2207 : {
2208 792352 : int numProcs = arrayP->numProcs;
2209 792352 : TransactionId *xip = snapshot->xip;
2210 792352 : int *pgprocnos = arrayP->pgprocnos;
2211 792352 : XidCacheStatus *subxidStates = ProcGlobal->subxidStates;
2212 792352 : uint8 *allStatusFlags = ProcGlobal->statusFlags;
2213 :
2214 : /*
2215 : * First collect set of pgxactoff/xids that need to be included in the
2216 : * snapshot.
2217 : */
2218 6944544 : for (int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)
2219 : {
2220 : /* Fetch xid just once - see GetNewTransactionId */
2221 6152192 : TransactionId xid = UINT32_ACCESS_ONCE(other_xids[pgxactoff]);
2222 : uint8 statusFlags;
2223 :
2224 : Assert(allProcs[arrayP->pgprocnos[pgxactoff]].pgxactoff == pgxactoff);
2225 :
2226 : /*
2227 : * If the transaction has no XID assigned, we can skip it; it
2228 : * won't have sub-XIDs either.
2229 : */
2230 6152192 : if (likely(xid == InvalidTransactionId))
2231 4559088 : continue;
2232 :
2233 : /*
2234 : * We don't include our own XIDs (if any) in the snapshot. It
2235 : * needs to be included in the xmin computation, but we did so
2236 : * outside the loop.
2237 : */
2238 1593104 : if (pgxactoff == mypgxactoff)
2239 108406 : continue;
2240 :
2241 : /*
2242 : * The only way we are able to get here with a non-normal xid is
2243 : * during bootstrap - with this backend using
2244 : * BootstrapTransactionId. But the above test should filter that
2245 : * out.
2246 : */
2247 : Assert(TransactionIdIsNormal(xid));
2248 :
2249 : /*
2250 : * If the XID is >= xmax, we can skip it; such transactions will
2251 : * be treated as running anyway (and any sub-XIDs will also be >=
2252 : * xmax).
2253 : */
2254 1484698 : if (!NormalTransactionIdPrecedes(xid, xmax))
2255 388400 : continue;
2256 :
2257 : /*
2258 : * Skip over backends doing logical decoding which manages xmin
2259 : * separately (check below) and ones running LAZY VACUUM.
2260 : */
2261 1096298 : statusFlags = allStatusFlags[pgxactoff];
2262 1096298 : if (statusFlags & (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM))
2263 168 : continue;
2264 :
2265 1096130 : if (NormalTransactionIdPrecedes(xid, xmin))
2266 586902 : xmin = xid;
2267 :
2268 : /* Add XID to snapshot. */
2269 1096130 : xip[count++] = xid;
2270 :
2271 : /*
2272 : * Save subtransaction XIDs if possible (if we've already
2273 : * overflowed, there's no point). Note that the subxact XIDs must
2274 : * be later than their parent, so no need to check them against
2275 : * xmin. We could filter against xmax, but it seems better not to
2276 : * do that much work while holding the ProcArrayLock.
2277 : *
2278 : * The other backend can add more subxids concurrently, but cannot
2279 : * remove any. Hence it's important to fetch nxids just once.
2280 : * Should be safe to use memcpy, though. (We needn't worry about
2281 : * missing any xids added concurrently, because they must postdate
2282 : * xmax.)
2283 : *
2284 : * Again, our own XIDs are not included in the snapshot.
2285 : */
2286 1096130 : if (!suboverflowed)
2287 : {
2288 :
2289 1096122 : if (subxidStates[pgxactoff].overflowed)
2290 872 : suboverflowed = true;
2291 : else
2292 : {
2293 1095250 : int nsubxids = subxidStates[pgxactoff].count;
2294 :
2295 1095250 : if (nsubxids > 0)
2296 : {
2297 11044 : int pgprocno = pgprocnos[pgxactoff];
2298 11044 : PGPROC *proc = &allProcs[pgprocno];
2299 :
2300 11044 : pg_read_barrier(); /* pairs with GetNewTransactionId */
2301 :
2302 11044 : memcpy(snapshot->subxip + subcount,
2303 11044 : proc->subxids.xids,
2304 : nsubxids * sizeof(TransactionId));
2305 11044 : subcount += nsubxids;
2306 : }
2307 : }
2308 : }
2309 : }
2310 : }
2311 : else
2312 : {
2313 : /*
2314 : * We're in hot standby, so get XIDs from KnownAssignedXids.
2315 : *
2316 : * We store all xids directly into subxip[]. Here's why:
2317 : *
2318 : * In recovery we don't know which xids are top-level and which are
2319 : * subxacts, a design choice that greatly simplifies xid processing.
2320 : *
2321 : * It seems like we would want to try to put xids into xip[] only, but
2322 : * that is fairly small. We would either need to make that bigger or
2323 : * to increase the rate at which we WAL-log xid assignment; neither is
2324 : * an appealing choice.
2325 : *
2326 : * We could try to store xids into xip[] first and then into subxip[]
2327 : * if there are too many xids. That only works if the snapshot doesn't
2328 : * overflow because we do not search subxip[] in that case. A simpler
2329 : * way is to just store all xids in the subxip array because this is
2330 : * by far the bigger array. We just leave the xip array empty.
2331 : *
2332 : * Either way we need to change the way XidInMVCCSnapshot() works
2333 : * depending upon when the snapshot was taken, or change normal
2334 : * snapshot processing so it matches.
2335 : *
2336 : * Note: It is possible for recovery to end before we finish taking
2337 : * the snapshot, and for newly assigned transaction ids to be added to
2338 : * the ProcArray. xmax cannot change while we hold ProcArrayLock, so
2339 : * those newly added transaction ids would be filtered away, so we
2340 : * need not be concerned about them.
2341 : */
2342 2970 : subcount = KnownAssignedXidsGetAndSetXmin(snapshot->subxip, &xmin,
2343 : xmax);
2344 :
2345 2970 : if (TransactionIdPrecedesOrEquals(xmin, procArray->lastOverflowedXid))
2346 12 : suboverflowed = true;
2347 : }
2348 :
2349 :
2350 : /*
2351 : * Fetch into local variable while ProcArrayLock is held - the
2352 : * LWLockRelease below is a barrier, ensuring this happens inside the
2353 : * lock.
2354 : */
2355 795322 : replication_slot_xmin = procArray->replication_slot_xmin;
2356 795322 : replication_slot_catalog_xmin = procArray->replication_slot_catalog_xmin;
2357 :
2358 795322 : if (!TransactionIdIsValid(MyProc->xmin))
2359 434196 : MyProc->xmin = TransactionXmin = xmin;
2360 :
2361 795322 : LWLockRelease(ProcArrayLock);
2362 :
2363 : /* maintain state for GlobalVis* */
2364 : {
2365 : TransactionId def_vis_xid;
2366 : TransactionId def_vis_xid_data;
2367 : FullTransactionId def_vis_fxid;
2368 : FullTransactionId def_vis_fxid_data;
2369 : FullTransactionId oldestfxid;
2370 :
2371 : /*
2372 : * Converting oldestXid is only safe when xid horizon cannot advance,
2373 : * i.e. holding locks. While we don't hold the lock anymore, all the
2374 : * necessary data has been gathered with lock held.
2375 : */
2376 795322 : oldestfxid = FullXidRelativeTo(latest_completed, oldestxid);
2377 :
2378 : /* Check whether there's a replication slot requiring an older xmin. */
2379 : def_vis_xid_data =
2380 795322 : TransactionIdOlder(xmin, replication_slot_xmin);
2381 :
2382 : /*
2383 : * Rows in non-shared, non-catalog tables possibly could be vacuumed
2384 : * if older than this xid.
2385 : */
2386 795322 : def_vis_xid = def_vis_xid_data;
2387 :
2388 : /*
2389 : * Check whether there's a replication slot requiring an older catalog
2390 : * xmin.
2391 : */
2392 : def_vis_xid =
2393 795322 : TransactionIdOlder(replication_slot_catalog_xmin, def_vis_xid);
2394 :
2395 795322 : def_vis_fxid = FullXidRelativeTo(latest_completed, def_vis_xid);
2396 795322 : def_vis_fxid_data = FullXidRelativeTo(latest_completed, def_vis_xid_data);
2397 :
2398 : /*
2399 : * Check if we can increase upper bound. As a previous
2400 : * GlobalVisUpdate() might have computed more aggressive values, don't
2401 : * overwrite them if so.
2402 : */
2403 : GlobalVisSharedRels.definitely_needed =
2404 795322 : FullTransactionIdNewer(def_vis_fxid,
2405 : GlobalVisSharedRels.definitely_needed);
2406 : GlobalVisCatalogRels.definitely_needed =
2407 795322 : FullTransactionIdNewer(def_vis_fxid,
2408 : GlobalVisCatalogRels.definitely_needed);
2409 : GlobalVisDataRels.definitely_needed =
2410 795322 : FullTransactionIdNewer(def_vis_fxid_data,
2411 : GlobalVisDataRels.definitely_needed);
2412 : /* See temp_oldest_nonremovable computation in ComputeXidHorizons() */
2413 795322 : if (TransactionIdIsNormal(myxid))
2414 : GlobalVisTempRels.definitely_needed =
2415 108202 : FullXidRelativeTo(latest_completed, myxid);
2416 : else
2417 : {
2418 687120 : GlobalVisTempRels.definitely_needed = latest_completed;
2419 687120 : FullTransactionIdAdvance(&GlobalVisTempRels.definitely_needed);
2420 : }
2421 :
2422 : /*
2423 : * Check if we know that we can initialize or increase the lower
2424 : * bound. Currently the only cheap way to do so is to use
2425 : * TransamVariables->oldestXid as input.
2426 : *
2427 : * We should definitely be able to do better. We could e.g. put a
2428 : * global lower bound value into TransamVariables.
2429 : */
2430 : GlobalVisSharedRels.maybe_needed =
2431 795322 : FullTransactionIdNewer(GlobalVisSharedRels.maybe_needed,
2432 : oldestfxid);
2433 : GlobalVisCatalogRels.maybe_needed =
2434 795322 : FullTransactionIdNewer(GlobalVisCatalogRels.maybe_needed,
2435 : oldestfxid);
2436 : GlobalVisDataRels.maybe_needed =
2437 795322 : FullTransactionIdNewer(GlobalVisDataRels.maybe_needed,
2438 : oldestfxid);
2439 : /* accurate value known */
2440 795322 : GlobalVisTempRels.maybe_needed = GlobalVisTempRels.definitely_needed;
2441 : }
2442 :
2443 795322 : RecentXmin = xmin;
2444 : Assert(TransactionIdPrecedesOrEquals(TransactionXmin, RecentXmin));
2445 :
2446 795322 : snapshot->xmin = xmin;
2447 795322 : snapshot->xmax = xmax;
2448 795322 : snapshot->xcnt = count;
2449 795322 : snapshot->subxcnt = subcount;
2450 795322 : snapshot->suboverflowed = suboverflowed;
2451 795322 : snapshot->snapXactCompletionCount = curXactCompletionCount;
2452 :
2453 795322 : snapshot->curcid = GetCurrentCommandId(false);
2454 :
2455 : /*
2456 : * This is a new snapshot, so set both refcounts are zero, and mark it as
2457 : * not copied in persistent memory.
2458 : */
2459 795322 : snapshot->active_count = 0;
2460 795322 : snapshot->regd_count = 0;
2461 795322 : snapshot->copied = false;
2462 :
2463 795322 : return snapshot;
2464 : }
2465 :
2466 : /*
2467 : * ProcArrayInstallImportedXmin -- install imported xmin into MyProc->xmin
2468 : *
2469 : * This is called when installing a snapshot imported from another
2470 : * transaction. To ensure that OldestXmin doesn't go backwards, we must
2471 : * check that the source transaction is still running, and we'd better do
2472 : * that atomically with installing the new xmin.
2473 : *
2474 : * Returns true if successful, false if source xact is no longer running.
2475 : */
2476 : bool
2477 32 : ProcArrayInstallImportedXmin(TransactionId xmin,
2478 : VirtualTransactionId *sourcevxid)
2479 : {
2480 32 : bool result = false;
2481 32 : ProcArrayStruct *arrayP = procArray;
2482 : int index;
2483 :
2484 : Assert(TransactionIdIsNormal(xmin));
2485 32 : if (!sourcevxid)
2486 0 : return false;
2487 :
2488 : /* Get lock so source xact can't end while we're doing this */
2489 32 : LWLockAcquire(ProcArrayLock, LW_SHARED);
2490 :
2491 : /*
2492 : * Find the PGPROC entry of the source transaction. (This could use
2493 : * GetPGProcByNumber(), unless it's a prepared xact. But this isn't
2494 : * performance critical.)
2495 : */
2496 32 : for (index = 0; index < arrayP->numProcs; index++)
2497 : {
2498 32 : int pgprocno = arrayP->pgprocnos[index];
2499 32 : PGPROC *proc = &allProcs[pgprocno];
2500 32 : int statusFlags = ProcGlobal->statusFlags[index];
2501 : TransactionId xid;
2502 :
2503 : /* Ignore procs running LAZY VACUUM */
2504 32 : if (statusFlags & PROC_IN_VACUUM)
2505 0 : continue;
2506 :
2507 : /* We are only interested in the specific virtual transaction. */
2508 32 : if (proc->vxid.procNumber != sourcevxid->procNumber)
2509 0 : continue;
2510 32 : if (proc->vxid.lxid != sourcevxid->localTransactionId)
2511 0 : continue;
2512 :
2513 : /*
2514 : * We check the transaction's database ID for paranoia's sake: if it's
2515 : * in another DB then its xmin does not cover us. Caller should have
2516 : * detected this already, so we just treat any funny cases as
2517 : * "transaction not found".
2518 : */
2519 32 : if (proc->databaseId != MyDatabaseId)
2520 0 : continue;
2521 :
2522 : /*
2523 : * Likewise, let's just make real sure its xmin does cover us.
2524 : */
2525 32 : xid = UINT32_ACCESS_ONCE(proc->xmin);
2526 32 : if (!TransactionIdIsNormal(xid) ||
2527 32 : !TransactionIdPrecedesOrEquals(xid, xmin))
2528 0 : continue;
2529 :
2530 : /*
2531 : * We're good. Install the new xmin. As in GetSnapshotData, set
2532 : * TransactionXmin too. (Note that because snapmgr.c called
2533 : * GetSnapshotData first, we'll be overwriting a valid xmin here, so
2534 : * we don't check that.)
2535 : */
2536 32 : MyProc->xmin = TransactionXmin = xmin;
2537 :
2538 32 : result = true;
2539 32 : break;
2540 : }
2541 :
2542 32 : LWLockRelease(ProcArrayLock);
2543 :
2544 32 : return result;
2545 : }
2546 :
2547 : /*
2548 : * ProcArrayInstallRestoredXmin -- install restored xmin into MyProc->xmin
2549 : *
2550 : * This is like ProcArrayInstallImportedXmin, but we have a pointer to the
2551 : * PGPROC of the transaction from which we imported the snapshot, rather than
2552 : * an XID.
2553 : *
2554 : * Note that this function also copies statusFlags from the source `proc` in
2555 : * order to avoid the case where MyProc's xmin needs to be skipped for
2556 : * computing xid horizon.
2557 : *
2558 : * Returns true if successful, false if source xact is no longer running.
2559 : */
2560 : bool
2561 3356 : ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
2562 : {
2563 3356 : bool result = false;
2564 : TransactionId xid;
2565 :
2566 : Assert(TransactionIdIsNormal(xmin));
2567 : Assert(proc != NULL);
2568 :
2569 : /*
2570 : * Get an exclusive lock so that we can copy statusFlags from source proc.
2571 : */
2572 3356 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
2573 :
2574 : /*
2575 : * Be certain that the referenced PGPROC has an advertised xmin which is
2576 : * no later than the one we're installing, so that the system-wide xmin
2577 : * can't go backwards. Also, make sure it's running in the same database,
2578 : * so that the per-database xmin cannot go backwards.
2579 : */
2580 3356 : xid = UINT32_ACCESS_ONCE(proc->xmin);
2581 3356 : if (proc->databaseId == MyDatabaseId &&
2582 3356 : TransactionIdIsNormal(xid) &&
2583 3356 : TransactionIdPrecedesOrEquals(xid, xmin))
2584 : {
2585 : /*
2586 : * Install xmin and propagate the statusFlags that affect how the
2587 : * value is interpreted by vacuum.
2588 : */
2589 3356 : MyProc->xmin = TransactionXmin = xmin;
2590 3356 : MyProc->statusFlags = (MyProc->statusFlags & ~PROC_XMIN_FLAGS) |
2591 3356 : (proc->statusFlags & PROC_XMIN_FLAGS);
2592 3356 : ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
2593 :
2594 3356 : result = true;
2595 : }
2596 :
2597 3356 : LWLockRelease(ProcArrayLock);
2598 :
2599 3356 : return result;
2600 : }
2601 :
2602 : /*
2603 : * GetRunningTransactionData -- returns information about running transactions.
2604 : *
2605 : * Similar to GetSnapshotData but returns more information. We include
2606 : * all PGPROCs with an assigned TransactionId, even VACUUM processes and
2607 : * prepared transactions.
2608 : *
2609 : * We acquire XidGenLock and ProcArrayLock, but the caller is responsible for
2610 : * releasing them. Acquiring XidGenLock ensures that no new XIDs enter the proc
2611 : * array until the caller has WAL-logged this snapshot, and releases the
2612 : * lock. Acquiring ProcArrayLock ensures that no transactions commit until the
2613 : * lock is released.
2614 : *
2615 : * The returned data structure is statically allocated; caller should not
2616 : * modify it, and must not assume it is valid past the next call.
2617 : *
2618 : * This is never executed during recovery so there is no need to look at
2619 : * KnownAssignedXids.
2620 : *
2621 : * Dummy PGPROCs from prepared transaction are included, meaning that this
2622 : * may return entries with duplicated TransactionId values coming from
2623 : * transaction finishing to prepare. Nothing is done about duplicated
2624 : * entries here to not hold on ProcArrayLock more than necessary.
2625 : *
2626 : * We don't worry about updating other counters, we want to keep this as
2627 : * simple as possible and leave GetSnapshotData() as the primary code for
2628 : * that bookkeeping.
2629 : *
2630 : * Note that if any transaction has overflowed its cached subtransactions
2631 : * then there is no real need include any subtransactions.
2632 : */
2633 : RunningTransactions
2634 2900 : GetRunningTransactionData(void)
2635 : {
2636 : /* result workspace */
2637 : static RunningTransactionsData CurrentRunningXactsData;
2638 :
2639 2900 : ProcArrayStruct *arrayP = procArray;
2640 2900 : TransactionId *other_xids = ProcGlobal->xids;
2641 2900 : RunningTransactions CurrentRunningXacts = &CurrentRunningXactsData;
2642 : TransactionId latestCompletedXid;
2643 : TransactionId oldestRunningXid;
2644 : TransactionId oldestDatabaseRunningXid;
2645 : TransactionId *xids;
2646 : int index;
2647 : int count;
2648 : int subcount;
2649 : bool suboverflowed;
2650 :
2651 : Assert(!RecoveryInProgress());
2652 :
2653 : /*
2654 : * Allocating space for maxProcs xids is usually overkill; numProcs would
2655 : * be sufficient. But it seems better to do the malloc while not holding
2656 : * the lock, so we can't look at numProcs. Likewise, we allocate much
2657 : * more subxip storage than is probably needed.
2658 : *
2659 : * Should only be allocated in bgwriter, since only ever executed during
2660 : * checkpoints.
2661 : */
2662 2900 : if (CurrentRunningXacts->xids == NULL)
2663 : {
2664 : /*
2665 : * First call
2666 : */
2667 1116 : CurrentRunningXacts->xids = (TransactionId *)
2668 1116 : malloc(TOTAL_MAX_CACHED_SUBXIDS * sizeof(TransactionId));
2669 1116 : if (CurrentRunningXacts->xids == NULL)
2670 0 : ereport(ERROR,
2671 : (errcode(ERRCODE_OUT_OF_MEMORY),
2672 : errmsg("out of memory")));
2673 : }
2674 :
2675 2900 : xids = CurrentRunningXacts->xids;
2676 :
2677 2900 : count = subcount = 0;
2678 2900 : suboverflowed = false;
2679 :
2680 : /*
2681 : * Ensure that no xids enter or leave the procarray while we obtain
2682 : * snapshot.
2683 : */
2684 2900 : LWLockAcquire(ProcArrayLock, LW_SHARED);
2685 2900 : LWLockAcquire(XidGenLock, LW_SHARED);
2686 :
2687 2900 : latestCompletedXid =
2688 2900 : XidFromFullTransactionId(TransamVariables->latestCompletedXid);
2689 2900 : oldestDatabaseRunningXid = oldestRunningXid =
2690 2900 : XidFromFullTransactionId(TransamVariables->nextXid);
2691 :
2692 : /*
2693 : * Spin over procArray collecting all xids
2694 : */
2695 14246 : for (index = 0; index < arrayP->numProcs; index++)
2696 : {
2697 : TransactionId xid;
2698 :
2699 : /* Fetch xid just once - see GetNewTransactionId */
2700 11346 : xid = UINT32_ACCESS_ONCE(other_xids[index]);
2701 :
2702 : /*
2703 : * We don't need to store transactions that don't have a TransactionId
2704 : * yet because they will not show as running on a standby server.
2705 : */
2706 11346 : if (!TransactionIdIsValid(xid))
2707 9372 : continue;
2708 :
2709 : /*
2710 : * Be careful not to exclude any xids before calculating the values of
2711 : * oldestRunningXid and suboverflowed, since these are used to clean
2712 : * up transaction information held on standbys.
2713 : */
2714 1974 : if (TransactionIdPrecedes(xid, oldestRunningXid))
2715 1332 : oldestRunningXid = xid;
2716 :
2717 : /*
2718 : * Also, update the oldest running xid within the current database. As
2719 : * fetching pgprocno and PGPROC could cause cache misses, we do cheap
2720 : * TransactionId comparison first.
2721 : */
2722 1974 : if (TransactionIdPrecedes(xid, oldestDatabaseRunningXid))
2723 : {
2724 1974 : int pgprocno = arrayP->pgprocnos[index];
2725 1974 : PGPROC *proc = &allProcs[pgprocno];
2726 :
2727 1974 : if (proc->databaseId == MyDatabaseId)
2728 424 : oldestDatabaseRunningXid = xid;
2729 : }
2730 :
2731 1974 : if (ProcGlobal->subxidStates[index].overflowed)
2732 4 : suboverflowed = true;
2733 :
2734 : /*
2735 : * If we wished to exclude xids this would be the right place for it.
2736 : * Procs with the PROC_IN_VACUUM flag set don't usually assign xids,
2737 : * but they do during truncation at the end when they get the lock and
2738 : * truncate, so it is not much of a problem to include them if they
2739 : * are seen and it is cleaner to include them.
2740 : */
2741 :
2742 1974 : xids[count++] = xid;
2743 : }
2744 :
2745 : /*
2746 : * Spin over procArray collecting all subxids, but only if there hasn't
2747 : * been a suboverflow.
2748 : */
2749 2900 : if (!suboverflowed)
2750 : {
2751 2896 : XidCacheStatus *other_subxidstates = ProcGlobal->subxidStates;
2752 :
2753 14230 : for (index = 0; index < arrayP->numProcs; index++)
2754 : {
2755 11334 : int pgprocno = arrayP->pgprocnos[index];
2756 11334 : PGPROC *proc = &allProcs[pgprocno];
2757 : int nsubxids;
2758 :
2759 : /*
2760 : * Save subtransaction XIDs. Other backends can't add or remove
2761 : * entries while we're holding XidGenLock.
2762 : */
2763 11334 : nsubxids = other_subxidstates[index].count;
2764 11334 : if (nsubxids > 0)
2765 : {
2766 : /* barrier not really required, as XidGenLock is held, but ... */
2767 48 : pg_read_barrier(); /* pairs with GetNewTransactionId */
2768 :
2769 48 : memcpy(&xids[count], proc->subxids.xids,
2770 : nsubxids * sizeof(TransactionId));
2771 48 : count += nsubxids;
2772 48 : subcount += nsubxids;
2773 :
2774 : /*
2775 : * Top-level XID of a transaction is always less than any of
2776 : * its subxids, so we don't need to check if any of the
2777 : * subxids are smaller than oldestRunningXid
2778 : */
2779 : }
2780 : }
2781 : }
2782 :
2783 : /*
2784 : * It's important *not* to include the limits set by slots here because
2785 : * snapbuild.c uses oldestRunningXid to manage its xmin horizon. If those
2786 : * were to be included here the initial value could never increase because
2787 : * of a circular dependency where slots only increase their limits when
2788 : * running xacts increases oldestRunningXid and running xacts only
2789 : * increases if slots do.
2790 : */
2791 :
2792 2900 : CurrentRunningXacts->xcnt = count - subcount;
2793 2900 : CurrentRunningXacts->subxcnt = subcount;
2794 2900 : CurrentRunningXacts->subxid_status = suboverflowed ? SUBXIDS_IN_SUBTRANS : SUBXIDS_IN_ARRAY;
2795 2900 : CurrentRunningXacts->nextXid = XidFromFullTransactionId(TransamVariables->nextXid);
2796 2900 : CurrentRunningXacts->oldestRunningXid = oldestRunningXid;
2797 2900 : CurrentRunningXacts->oldestDatabaseRunningXid = oldestDatabaseRunningXid;
2798 2900 : CurrentRunningXacts->latestCompletedXid = latestCompletedXid;
2799 :
2800 : Assert(TransactionIdIsValid(CurrentRunningXacts->nextXid));
2801 : Assert(TransactionIdIsValid(CurrentRunningXacts->oldestRunningXid));
2802 : Assert(TransactionIdIsNormal(CurrentRunningXacts->latestCompletedXid));
2803 :
2804 : /* We don't release the locks here, the caller is responsible for that */
2805 :
2806 2900 : return CurrentRunningXacts;
2807 : }
2808 :
2809 : /*
2810 : * GetOldestActiveTransactionId()
2811 : *
2812 : * Similar to GetSnapshotData but returns just oldestActiveXid. We include
2813 : * all PGPROCs with an assigned TransactionId, even VACUUM processes.
2814 : *
2815 : * If allDbs is true, we look at all databases, though there is no need to
2816 : * include WALSender since this has no effect on hot standby conflicts. If
2817 : * allDbs is false, skip processes attached to other databases.
2818 : *
2819 : * This is never executed during recovery so there is no need to look at
2820 : * KnownAssignedXids.
2821 : *
2822 : * We don't worry about updating other counters, we want to keep this as
2823 : * simple as possible and leave GetSnapshotData() as the primary code for
2824 : * that bookkeeping.
2825 : *
2826 : * inCommitOnly indicates getting the oldestActiveXid among the transactions
2827 : * in the commit critical section.
2828 : */
2829 : TransactionId
2830 7034 : GetOldestActiveTransactionId(bool inCommitOnly, bool allDbs)
2831 : {
2832 7034 : ProcArrayStruct *arrayP = procArray;
2833 7034 : TransactionId *other_xids = ProcGlobal->xids;
2834 : TransactionId oldestRunningXid;
2835 : int index;
2836 :
2837 : Assert(!RecoveryInProgress());
2838 :
2839 : /*
2840 : * Read nextXid, as the upper bound of what's still active.
2841 : *
2842 : * Reading a TransactionId is atomic, but we must grab the lock to make
2843 : * sure that all XIDs < nextXid are already present in the proc array (or
2844 : * have already completed), when we spin over it.
2845 : */
2846 7034 : LWLockAcquire(XidGenLock, LW_SHARED);
2847 7034 : oldestRunningXid = XidFromFullTransactionId(TransamVariables->nextXid);
2848 7034 : LWLockRelease(XidGenLock);
2849 :
2850 : /*
2851 : * Spin over procArray collecting all xids and subxids.
2852 : */
2853 7034 : LWLockAcquire(ProcArrayLock, LW_SHARED);
2854 39676 : for (index = 0; index < arrayP->numProcs; index++)
2855 : {
2856 : TransactionId xid;
2857 32642 : int pgprocno = arrayP->pgprocnos[index];
2858 32642 : PGPROC *proc = &allProcs[pgprocno];
2859 :
2860 : /* Fetch xid just once - see GetNewTransactionId */
2861 32642 : xid = UINT32_ACCESS_ONCE(other_xids[index]);
2862 :
2863 32642 : if (!TransactionIdIsNormal(xid))
2864 25930 : continue;
2865 :
2866 6712 : if (inCommitOnly &&
2867 4876 : (proc->delayChkptFlags & DELAY_CHKPT_IN_COMMIT) == 0)
2868 4876 : continue;
2869 :
2870 1836 : if (!allDbs && proc->databaseId != MyDatabaseId)
2871 0 : continue;
2872 :
2873 1836 : if (TransactionIdPrecedes(xid, oldestRunningXid))
2874 1248 : oldestRunningXid = xid;
2875 :
2876 : /*
2877 : * Top-level XID of a transaction is always less than any of its
2878 : * subxids, so we don't need to check if any of the subxids are
2879 : * smaller than oldestRunningXid
2880 : */
2881 : }
2882 7034 : LWLockRelease(ProcArrayLock);
2883 :
2884 7034 : return oldestRunningXid;
2885 : }
2886 :
2887 : /*
2888 : * GetOldestSafeDecodingTransactionId -- lowest xid not affected by vacuum
2889 : *
2890 : * Returns the oldest xid that we can guarantee not to have been affected by
2891 : * vacuum, i.e. no rows >= that xid have been vacuumed away unless the
2892 : * transaction aborted. Note that the value can (and most of the time will) be
2893 : * much more conservative than what really has been affected by vacuum, but we
2894 : * currently don't have better data available.
2895 : *
2896 : * This is useful to initialize the cutoff xid after which a new changeset
2897 : * extraction replication slot can start decoding changes.
2898 : *
2899 : * Must be called with ProcArrayLock held either shared or exclusively,
2900 : * although most callers will want to use exclusive mode since it is expected
2901 : * that the caller will immediately use the xid to peg the xmin horizon.
2902 : */
2903 : TransactionId
2904 1372 : GetOldestSafeDecodingTransactionId(bool catalogOnly)
2905 : {
2906 1372 : ProcArrayStruct *arrayP = procArray;
2907 : TransactionId oldestSafeXid;
2908 : int index;
2909 1372 : bool recovery_in_progress = RecoveryInProgress();
2910 :
2911 : Assert(LWLockHeldByMe(ProcArrayLock));
2912 :
2913 : /*
2914 : * Acquire XidGenLock, so no transactions can acquire an xid while we're
2915 : * running. If no transaction with xid were running concurrently a new xid
2916 : * could influence the RecentXmin et al.
2917 : *
2918 : * We initialize the computation to nextXid since that's guaranteed to be
2919 : * a safe, albeit pessimal, value.
2920 : */
2921 1372 : LWLockAcquire(XidGenLock, LW_SHARED);
2922 1372 : oldestSafeXid = XidFromFullTransactionId(TransamVariables->nextXid);
2923 :
2924 : /*
2925 : * If there's already a slot pegging the xmin horizon, we can start with
2926 : * that value, it's guaranteed to be safe since it's computed by this
2927 : * routine initially and has been enforced since. We can always use the
2928 : * slot's general xmin horizon, but the catalog horizon is only usable
2929 : * when only catalog data is going to be looked at.
2930 : */
2931 1826 : if (TransactionIdIsValid(procArray->replication_slot_xmin) &&
2932 454 : TransactionIdPrecedes(procArray->replication_slot_xmin,
2933 : oldestSafeXid))
2934 24 : oldestSafeXid = procArray->replication_slot_xmin;
2935 :
2936 1372 : if (catalogOnly &&
2937 710 : TransactionIdIsValid(procArray->replication_slot_catalog_xmin) &&
2938 146 : TransactionIdPrecedes(procArray->replication_slot_catalog_xmin,
2939 : oldestSafeXid))
2940 56 : oldestSafeXid = procArray->replication_slot_catalog_xmin;
2941 :
2942 : /*
2943 : * If we're not in recovery, we walk over the procarray and collect the
2944 : * lowest xid. Since we're called with ProcArrayLock held and have
2945 : * acquired XidGenLock, no entries can vanish concurrently, since
2946 : * ProcGlobal->xids[i] is only set with XidGenLock held and only cleared
2947 : * with ProcArrayLock held.
2948 : *
2949 : * In recovery we can't lower the safe value besides what we've computed
2950 : * above, so we'll have to wait a bit longer there. We unfortunately can
2951 : * *not* use KnownAssignedXidsGetOldestXmin() since the KnownAssignedXids
2952 : * machinery can miss values and return an older value than is safe.
2953 : */
2954 1372 : if (!recovery_in_progress)
2955 : {
2956 1308 : TransactionId *other_xids = ProcGlobal->xids;
2957 :
2958 : /*
2959 : * Spin over procArray collecting min(ProcGlobal->xids[i])
2960 : */
2961 6700 : for (index = 0; index < arrayP->numProcs; index++)
2962 : {
2963 : TransactionId xid;
2964 :
2965 : /* Fetch xid just once - see GetNewTransactionId */
2966 5392 : xid = UINT32_ACCESS_ONCE(other_xids[index]);
2967 :
2968 5392 : if (!TransactionIdIsNormal(xid))
2969 5374 : continue;
2970 :
2971 18 : if (TransactionIdPrecedes(xid, oldestSafeXid))
2972 14 : oldestSafeXid = xid;
2973 : }
2974 : }
2975 :
2976 1372 : LWLockRelease(XidGenLock);
2977 :
2978 1372 : return oldestSafeXid;
2979 : }
2980 :
2981 : /*
2982 : * GetVirtualXIDsDelayingChkpt -- Get the VXIDs of transactions that are
2983 : * delaying checkpoint because they have critical actions in progress.
2984 : *
2985 : * Constructs an array of VXIDs of transactions that are currently in commit
2986 : * critical sections, as shown by having specified delayChkptFlags bits set
2987 : * in their PGPROC.
2988 : *
2989 : * Returns a palloc'd array that should be freed by the caller.
2990 : * *nvxids is the number of valid entries.
2991 : *
2992 : * Note that because backends set or clear delayChkptFlags without holding any
2993 : * lock, the result is somewhat indeterminate, but we don't really care. Even
2994 : * in a multiprocessor with delayed writes to shared memory, it should be
2995 : * certain that setting of delayChkptFlags will propagate to shared memory
2996 : * when the backend takes a lock, so we cannot fail to see a virtual xact as
2997 : * delayChkptFlags if it's already inserted its commit record. Whether it
2998 : * takes a little while for clearing of delayChkptFlags to propagate is
2999 : * unimportant for correctness.
3000 : */
3001 : VirtualTransactionId *
3002 6368 : GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
3003 : {
3004 : VirtualTransactionId *vxids;
3005 6368 : ProcArrayStruct *arrayP = procArray;
3006 6368 : int count = 0;
3007 : int index;
3008 :
3009 : Assert(type != 0);
3010 :
3011 : /* allocate what's certainly enough result space */
3012 6368 : vxids = palloc_array(VirtualTransactionId, arrayP->maxProcs);
3013 :
3014 6368 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3015 :
3016 20954 : for (index = 0; index < arrayP->numProcs; index++)
3017 : {
3018 14586 : int pgprocno = arrayP->pgprocnos[index];
3019 14586 : PGPROC *proc = &allProcs[pgprocno];
3020 :
3021 14586 : if ((proc->delayChkptFlags & type) != 0)
3022 : {
3023 : VirtualTransactionId vxid;
3024 :
3025 94 : GET_VXID_FROM_PGPROC(vxid, *proc);
3026 94 : if (VirtualTransactionIdIsValid(vxid))
3027 94 : vxids[count++] = vxid;
3028 : }
3029 : }
3030 :
3031 6368 : LWLockRelease(ProcArrayLock);
3032 :
3033 6368 : *nvxids = count;
3034 6368 : return vxids;
3035 : }
3036 :
3037 : /*
3038 : * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying?
3039 : *
3040 : * This is used with the results of GetVirtualXIDsDelayingChkpt to see if any
3041 : * of the specified VXIDs are still in critical sections of code.
3042 : *
3043 : * Note: this is O(N^2) in the number of vxacts that are/were delaying, but
3044 : * those numbers should be small enough for it not to be a problem.
3045 : */
3046 : bool
3047 92 : HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
3048 : {
3049 92 : bool result = false;
3050 92 : ProcArrayStruct *arrayP = procArray;
3051 : int index;
3052 :
3053 : Assert(type != 0);
3054 :
3055 92 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3056 :
3057 890 : for (index = 0; index < arrayP->numProcs; index++)
3058 : {
3059 816 : int pgprocno = arrayP->pgprocnos[index];
3060 816 : PGPROC *proc = &allProcs[pgprocno];
3061 : VirtualTransactionId vxid;
3062 :
3063 816 : GET_VXID_FROM_PGPROC(vxid, *proc);
3064 :
3065 816 : if ((proc->delayChkptFlags & type) != 0 &&
3066 72 : VirtualTransactionIdIsValid(vxid))
3067 : {
3068 : int i;
3069 :
3070 154 : for (i = 0; i < nvxids; i++)
3071 : {
3072 100 : if (VirtualTransactionIdEquals(vxid, vxids[i]))
3073 : {
3074 18 : result = true;
3075 18 : break;
3076 : }
3077 : }
3078 72 : if (result)
3079 18 : break;
3080 : }
3081 : }
3082 :
3083 92 : LWLockRelease(ProcArrayLock);
3084 :
3085 92 : return result;
3086 : }
3087 :
3088 : /*
3089 : * ProcNumberGetProc -- get a backend's PGPROC given its proc number
3090 : *
3091 : * The result may be out of date arbitrarily quickly, so the caller
3092 : * must be careful about how this information is used. NULL is
3093 : * returned if the backend is not active.
3094 : */
3095 : PGPROC *
3096 1210 : ProcNumberGetProc(ProcNumber procNumber)
3097 : {
3098 : PGPROC *result;
3099 :
3100 1210 : if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
3101 2 : return NULL;
3102 1208 : result = GetPGProcByNumber(procNumber);
3103 :
3104 1208 : if (result->pid == 0)
3105 6 : return NULL;
3106 :
3107 1202 : return result;
3108 : }
3109 :
3110 : /*
3111 : * ProcNumberGetTransactionIds -- get a backend's transaction status
3112 : *
3113 : * Get the xid, xmin, nsubxid and overflow status of the backend. The
3114 : * result may be out of date arbitrarily quickly, so the caller must be
3115 : * careful about how this information is used.
3116 : */
3117 : void
3118 22352 : ProcNumberGetTransactionIds(ProcNumber procNumber, TransactionId *xid,
3119 : TransactionId *xmin, int *nsubxid, bool *overflowed)
3120 : {
3121 : PGPROC *proc;
3122 :
3123 22352 : *xid = InvalidTransactionId;
3124 22352 : *xmin = InvalidTransactionId;
3125 22352 : *nsubxid = 0;
3126 22352 : *overflowed = false;
3127 :
3128 22352 : if (procNumber < 0 || procNumber >= ProcGlobal->allProcCount)
3129 0 : return;
3130 22352 : proc = GetPGProcByNumber(procNumber);
3131 :
3132 : /* Need to lock out additions/removals of backends */
3133 22352 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3134 :
3135 22352 : if (proc->pid != 0)
3136 : {
3137 22352 : *xid = proc->xid;
3138 22352 : *xmin = proc->xmin;
3139 22352 : *nsubxid = proc->subxidStatus.count;
3140 22352 : *overflowed = proc->subxidStatus.overflowed;
3141 : }
3142 :
3143 22352 : LWLockRelease(ProcArrayLock);
3144 : }
3145 :
3146 : /*
3147 : * BackendPidGetProc -- get a backend's PGPROC given its PID
3148 : *
3149 : * Returns NULL if not found. Note that it is up to the caller to be
3150 : * sure that the question remains meaningful for long enough for the
3151 : * answer to be used ...
3152 : */
3153 : PGPROC *
3154 24724 : BackendPidGetProc(int pid)
3155 : {
3156 : PGPROC *result;
3157 :
3158 24724 : if (pid == 0) /* never match dummy PGPROCs */
3159 6 : return NULL;
3160 :
3161 24718 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3162 :
3163 24718 : result = BackendPidGetProcWithLock(pid);
3164 :
3165 24718 : LWLockRelease(ProcArrayLock);
3166 :
3167 24718 : return result;
3168 : }
3169 :
3170 : /*
3171 : * BackendPidGetProcWithLock -- get a backend's PGPROC given its PID
3172 : *
3173 : * Same as above, except caller must be holding ProcArrayLock. The found
3174 : * entry, if any, can be assumed to be valid as long as the lock remains held.
3175 : */
3176 : PGPROC *
3177 28548 : BackendPidGetProcWithLock(int pid)
3178 : {
3179 28548 : PGPROC *result = NULL;
3180 28548 : ProcArrayStruct *arrayP = procArray;
3181 : int index;
3182 :
3183 28548 : if (pid == 0) /* never match dummy PGPROCs */
3184 0 : return NULL;
3185 :
3186 112102 : for (index = 0; index < arrayP->numProcs; index++)
3187 : {
3188 99842 : PGPROC *proc = &allProcs[arrayP->pgprocnos[index]];
3189 :
3190 99842 : if (proc->pid == pid)
3191 : {
3192 16288 : result = proc;
3193 16288 : break;
3194 : }
3195 : }
3196 :
3197 28548 : return result;
3198 : }
3199 :
3200 : /*
3201 : * BackendXidGetPid -- get a backend's pid given its XID
3202 : *
3203 : * Returns 0 if not found or it's a prepared transaction. Note that
3204 : * it is up to the caller to be sure that the question remains
3205 : * meaningful for long enough for the answer to be used ...
3206 : *
3207 : * Only main transaction Ids are considered. This function is mainly
3208 : * useful for determining what backend owns a lock.
3209 : *
3210 : * Beware that not every xact has an XID assigned. However, as long as you
3211 : * only call this using an XID found on disk, you're safe.
3212 : */
3213 : int
3214 60 : BackendXidGetPid(TransactionId xid)
3215 : {
3216 60 : int result = 0;
3217 60 : ProcArrayStruct *arrayP = procArray;
3218 60 : TransactionId *other_xids = ProcGlobal->xids;
3219 : int index;
3220 :
3221 60 : if (xid == InvalidTransactionId) /* never match invalid xid */
3222 0 : return 0;
3223 :
3224 60 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3225 :
3226 184 : for (index = 0; index < arrayP->numProcs; index++)
3227 : {
3228 168 : if (other_xids[index] == xid)
3229 : {
3230 44 : int pgprocno = arrayP->pgprocnos[index];
3231 44 : PGPROC *proc = &allProcs[pgprocno];
3232 :
3233 44 : result = proc->pid;
3234 44 : break;
3235 : }
3236 : }
3237 :
3238 60 : LWLockRelease(ProcArrayLock);
3239 :
3240 60 : return result;
3241 : }
3242 :
3243 : /*
3244 : * IsBackendPid -- is a given pid a running backend
3245 : *
3246 : * This is not called by the backend, but is called by external modules.
3247 : */
3248 : bool
3249 4 : IsBackendPid(int pid)
3250 : {
3251 4 : return (BackendPidGetProc(pid) != NULL);
3252 : }
3253 :
3254 :
3255 : /*
3256 : * GetCurrentVirtualXIDs -- returns an array of currently active VXIDs.
3257 : *
3258 : * The array is palloc'd. The number of valid entries is returned into *nvxids.
3259 : *
3260 : * The arguments allow filtering the set of VXIDs returned. Our own process
3261 : * is always skipped. In addition:
3262 : * If limitXmin is not InvalidTransactionId, skip processes with
3263 : * xmin > limitXmin.
3264 : * If excludeXmin0 is true, skip processes with xmin = 0.
3265 : * If allDbs is false, skip processes attached to other databases.
3266 : * If excludeVacuum isn't zero, skip processes for which
3267 : * (statusFlags & excludeVacuum) is not zero.
3268 : *
3269 : * Note: the purpose of the limitXmin and excludeXmin0 parameters is to
3270 : * allow skipping backends whose oldest live snapshot is no older than
3271 : * some snapshot we have. Since we examine the procarray with only shared
3272 : * lock, there are race conditions: a backend could set its xmin just after
3273 : * we look. Indeed, on multiprocessors with weak memory ordering, the
3274 : * other backend could have set its xmin *before* we look. We know however
3275 : * that such a backend must have held shared ProcArrayLock overlapping our
3276 : * own hold of ProcArrayLock, else we would see its xmin update. Therefore,
3277 : * any snapshot the other backend is taking concurrently with our scan cannot
3278 : * consider any transactions as still running that we think are committed
3279 : * (since backends must hold ProcArrayLock exclusive to commit).
3280 : */
3281 : VirtualTransactionId *
3282 792 : GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0,
3283 : bool allDbs, int excludeVacuum,
3284 : int *nvxids)
3285 : {
3286 : VirtualTransactionId *vxids;
3287 792 : ProcArrayStruct *arrayP = procArray;
3288 792 : int count = 0;
3289 : int index;
3290 :
3291 : /* allocate what's certainly enough result space */
3292 792 : vxids = palloc_array(VirtualTransactionId, arrayP->maxProcs);
3293 :
3294 792 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3295 :
3296 4808 : for (index = 0; index < arrayP->numProcs; index++)
3297 : {
3298 4016 : int pgprocno = arrayP->pgprocnos[index];
3299 4016 : PGPROC *proc = &allProcs[pgprocno];
3300 4016 : uint8 statusFlags = ProcGlobal->statusFlags[index];
3301 :
3302 4016 : if (proc == MyProc)
3303 792 : continue;
3304 :
3305 3224 : if (excludeVacuum & statusFlags)
3306 44 : continue;
3307 :
3308 3180 : if (allDbs || proc->databaseId == MyDatabaseId)
3309 : {
3310 : /* Fetch xmin just once - might change on us */
3311 1428 : TransactionId pxmin = UINT32_ACCESS_ONCE(proc->xmin);
3312 :
3313 1428 : if (excludeXmin0 && !TransactionIdIsValid(pxmin))
3314 844 : continue;
3315 :
3316 : /*
3317 : * InvalidTransactionId precedes all other XIDs, so a proc that
3318 : * hasn't set xmin yet will not be rejected by this test.
3319 : */
3320 1168 : if (!TransactionIdIsValid(limitXmin) ||
3321 584 : TransactionIdPrecedesOrEquals(pxmin, limitXmin))
3322 : {
3323 : VirtualTransactionId vxid;
3324 :
3325 562 : GET_VXID_FROM_PGPROC(vxid, *proc);
3326 562 : if (VirtualTransactionIdIsValid(vxid))
3327 562 : vxids[count++] = vxid;
3328 : }
3329 : }
3330 : }
3331 :
3332 792 : LWLockRelease(ProcArrayLock);
3333 :
3334 792 : *nvxids = count;
3335 792 : return vxids;
3336 : }
3337 :
3338 : /*
3339 : * GetConflictingVirtualXIDs -- returns an array of currently active VXIDs.
3340 : *
3341 : * Usage is limited to conflict resolution during recovery on standby servers.
3342 : * limitXmin is supplied as either a cutoff with snapshotConflictHorizon
3343 : * semantics, or InvalidTransactionId in cases where caller cannot accurately
3344 : * determine a safe snapshotConflictHorizon value.
3345 : *
3346 : * If limitXmin is InvalidTransactionId then we want to kill everybody,
3347 : * so we're not worried if they have a snapshot or not, nor does it really
3348 : * matter what type of lock we hold. Caller must avoid calling here with
3349 : * snapshotConflictHorizon style cutoffs that were set to InvalidTransactionId
3350 : * during original execution, since that actually indicates that there is
3351 : * definitely no need for a recovery conflict (the snapshotConflictHorizon
3352 : * convention for InvalidTransactionId values is the opposite of our own!).
3353 : *
3354 : * All callers that are checking xmins always now supply a valid and useful
3355 : * value for limitXmin. The limitXmin is always lower than the lowest
3356 : * numbered KnownAssignedXid that is not already a FATAL error. This is
3357 : * because we only care about cleanup records that are cleaning up tuple
3358 : * versions from committed transactions. In that case they will only occur
3359 : * at the point where the record is less than the lowest running xid. That
3360 : * allows us to say that if any backend takes a snapshot concurrently with
3361 : * us then the conflict assessment made here would never include the snapshot
3362 : * that is being derived. So we take LW_SHARED on the ProcArray and allow
3363 : * concurrent snapshots when limitXmin is valid. We might think about adding
3364 : * Assert(limitXmin < lowest(KnownAssignedXids))
3365 : * but that would not be true in the case of FATAL errors lagging in array,
3366 : * but we already know those are bogus anyway, so we skip that test.
3367 : *
3368 : * If dbOid is valid we skip backends attached to other databases.
3369 : *
3370 : * Be careful to *not* pfree the result from this function. We reuse
3371 : * this array sufficiently often that we use malloc for the result.
3372 : */
3373 : VirtualTransactionId *
3374 27316 : GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
3375 : {
3376 : static VirtualTransactionId *vxids;
3377 27316 : ProcArrayStruct *arrayP = procArray;
3378 27316 : int count = 0;
3379 : int index;
3380 :
3381 : /*
3382 : * If first time through, get workspace to remember main XIDs in. We
3383 : * malloc it permanently to avoid repeated palloc/pfree overhead. Allow
3384 : * result space, remembering room for a terminator.
3385 : */
3386 27316 : if (vxids == NULL)
3387 : {
3388 46 : vxids = (VirtualTransactionId *)
3389 46 : malloc(sizeof(VirtualTransactionId) * (arrayP->maxProcs + 1));
3390 46 : if (vxids == NULL)
3391 0 : ereport(ERROR,
3392 : (errcode(ERRCODE_OUT_OF_MEMORY),
3393 : errmsg("out of memory")));
3394 : }
3395 :
3396 27316 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3397 :
3398 27610 : for (index = 0; index < arrayP->numProcs; index++)
3399 : {
3400 294 : int pgprocno = arrayP->pgprocnos[index];
3401 294 : PGPROC *proc = &allProcs[pgprocno];
3402 :
3403 : /* Exclude prepared transactions */
3404 294 : if (proc->pid == 0)
3405 0 : continue;
3406 :
3407 294 : if (!OidIsValid(dbOid) ||
3408 278 : proc->databaseId == dbOid)
3409 : {
3410 : /* Fetch xmin just once - can't change on us, but good coding */
3411 36 : TransactionId pxmin = UINT32_ACCESS_ONCE(proc->xmin);
3412 :
3413 : /*
3414 : * We ignore an invalid pxmin because this means that backend has
3415 : * no snapshot currently. We hold a Share lock to avoid contention
3416 : * with users taking snapshots. That is not a problem because the
3417 : * current xmin is always at least one higher than the latest
3418 : * removed xid, so any new snapshot would never conflict with the
3419 : * test here.
3420 : */
3421 36 : if (!TransactionIdIsValid(limitXmin) ||
3422 8 : (TransactionIdIsValid(pxmin) && !TransactionIdFollows(pxmin, limitXmin)))
3423 : {
3424 : VirtualTransactionId vxid;
3425 :
3426 4 : GET_VXID_FROM_PGPROC(vxid, *proc);
3427 4 : if (VirtualTransactionIdIsValid(vxid))
3428 4 : vxids[count++] = vxid;
3429 : }
3430 : }
3431 : }
3432 :
3433 27316 : LWLockRelease(ProcArrayLock);
3434 :
3435 : /* add the terminator */
3436 27316 : vxids[count].procNumber = INVALID_PROC_NUMBER;
3437 27316 : vxids[count].localTransactionId = InvalidLocalTransactionId;
3438 :
3439 27316 : return vxids;
3440 : }
3441 :
3442 : /*
3443 : * SignalVirtualTransaction - used in recovery conflict processing
3444 : *
3445 : * Returns pid of the process signaled, or 0 if not found.
3446 : */
3447 : pid_t
3448 10 : SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)
3449 : {
3450 10 : ProcArrayStruct *arrayP = procArray;
3451 : int index;
3452 10 : pid_t pid = 0;
3453 :
3454 10 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3455 :
3456 10 : for (index = 0; index < arrayP->numProcs; index++)
3457 : {
3458 10 : int pgprocno = arrayP->pgprocnos[index];
3459 10 : PGPROC *proc = &allProcs[pgprocno];
3460 : VirtualTransactionId procvxid;
3461 :
3462 10 : GET_VXID_FROM_PGPROC(procvxid, *proc);
3463 :
3464 10 : if (procvxid.procNumber == vxid.procNumber &&
3465 10 : procvxid.localTransactionId == vxid.localTransactionId)
3466 : {
3467 10 : pid = proc->pid;
3468 10 : if (pid != 0)
3469 : {
3470 : /*
3471 : * Kill the pid if it's still here. If not, that's what we
3472 : * wanted so ignore any errors.
3473 : */
3474 10 : (void) SendProcSignal(pid, sigmode, vxid.procNumber);
3475 : }
3476 10 : break;
3477 : }
3478 : }
3479 :
3480 10 : LWLockRelease(ProcArrayLock);
3481 :
3482 10 : return pid;
3483 : }
3484 :
3485 : /*
3486 : * MinimumActiveBackends --- count backends (other than myself) that are
3487 : * in active transactions. Return true if the count exceeds the
3488 : * minimum threshold passed. This is used as a heuristic to decide if
3489 : * a pre-XLOG-flush delay is worthwhile during commit.
3490 : *
3491 : * Do not count backends that are blocked waiting for locks, since they are
3492 : * not going to get to run until someone else commits.
3493 : */
3494 : bool
3495 0 : MinimumActiveBackends(int min)
3496 : {
3497 0 : ProcArrayStruct *arrayP = procArray;
3498 0 : int count = 0;
3499 : int index;
3500 :
3501 : /* Quick short-circuit if no minimum is specified */
3502 0 : if (min == 0)
3503 0 : return true;
3504 :
3505 : /*
3506 : * Note: for speed, we don't acquire ProcArrayLock. This is a little bit
3507 : * bogus, but since we are only testing fields for zero or nonzero, it
3508 : * should be OK. The result is only used for heuristic purposes anyway...
3509 : */
3510 0 : for (index = 0; index < arrayP->numProcs; index++)
3511 : {
3512 0 : int pgprocno = arrayP->pgprocnos[index];
3513 0 : PGPROC *proc = &allProcs[pgprocno];
3514 :
3515 : /*
3516 : * Since we're not holding a lock, need to be prepared to deal with
3517 : * garbage, as someone could have incremented numProcs but not yet
3518 : * filled the structure.
3519 : *
3520 : * If someone just decremented numProcs, 'proc' could also point to a
3521 : * PGPROC entry that's no longer in the array. It still points to a
3522 : * PGPROC struct, though, because freed PGPROC entries just go to the
3523 : * free list and are recycled. Its contents are nonsense in that case,
3524 : * but that's acceptable for this function.
3525 : */
3526 0 : if (pgprocno == -1)
3527 0 : continue; /* do not count deleted entries */
3528 0 : if (proc == MyProc)
3529 0 : continue; /* do not count myself */
3530 0 : if (proc->xid == InvalidTransactionId)
3531 0 : continue; /* do not count if no XID assigned */
3532 0 : if (proc->pid == 0)
3533 0 : continue; /* do not count prepared xacts */
3534 0 : if (proc->waitLock != NULL)
3535 0 : continue; /* do not count if blocked on a lock */
3536 0 : count++;
3537 0 : if (count >= min)
3538 0 : break;
3539 : }
3540 :
3541 0 : return count >= min;
3542 : }
3543 :
3544 : /*
3545 : * CountDBBackends --- count backends that are using specified database
3546 : */
3547 : int
3548 32 : CountDBBackends(Oid databaseid)
3549 : {
3550 32 : ProcArrayStruct *arrayP = procArray;
3551 32 : int count = 0;
3552 : int index;
3553 :
3554 32 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3555 :
3556 46 : for (index = 0; index < arrayP->numProcs; index++)
3557 : {
3558 14 : int pgprocno = arrayP->pgprocnos[index];
3559 14 : PGPROC *proc = &allProcs[pgprocno];
3560 :
3561 14 : if (proc->pid == 0)
3562 0 : continue; /* do not count prepared xacts */
3563 14 : if (!OidIsValid(databaseid) ||
3564 14 : proc->databaseId == databaseid)
3565 4 : count++;
3566 : }
3567 :
3568 32 : LWLockRelease(ProcArrayLock);
3569 :
3570 32 : return count;
3571 : }
3572 :
3573 : /*
3574 : * CountDBConnections --- counts database backends (only regular backends)
3575 : */
3576 : int
3577 0 : CountDBConnections(Oid databaseid)
3578 : {
3579 0 : ProcArrayStruct *arrayP = procArray;
3580 0 : int count = 0;
3581 : int index;
3582 :
3583 0 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3584 :
3585 0 : for (index = 0; index < arrayP->numProcs; index++)
3586 : {
3587 0 : int pgprocno = arrayP->pgprocnos[index];
3588 0 : PGPROC *proc = &allProcs[pgprocno];
3589 :
3590 0 : if (proc->pid == 0)
3591 0 : continue; /* do not count prepared xacts */
3592 0 : if (proc->backendType != B_BACKEND)
3593 0 : continue; /* count only regular backend processes */
3594 0 : if (!OidIsValid(databaseid) ||
3595 0 : proc->databaseId == databaseid)
3596 0 : count++;
3597 : }
3598 :
3599 0 : LWLockRelease(ProcArrayLock);
3600 :
3601 0 : return count;
3602 : }
3603 :
3604 : /*
3605 : * CancelDBBackends --- cancel backends that are using specified database
3606 : */
3607 : void
3608 18 : CancelDBBackends(Oid databaseid, ProcSignalReason sigmode)
3609 : {
3610 18 : ProcArrayStruct *arrayP = procArray;
3611 : int index;
3612 :
3613 : /* tell all backends to die */
3614 18 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
3615 :
3616 36 : for (index = 0; index < arrayP->numProcs; index++)
3617 : {
3618 18 : int pgprocno = arrayP->pgprocnos[index];
3619 18 : PGPROC *proc = &allProcs[pgprocno];
3620 :
3621 18 : if (databaseid == InvalidOid || proc->databaseId == databaseid)
3622 : {
3623 : VirtualTransactionId procvxid;
3624 : pid_t pid;
3625 :
3626 18 : GET_VXID_FROM_PGPROC(procvxid, *proc);
3627 :
3628 18 : pid = proc->pid;
3629 18 : if (pid != 0)
3630 : {
3631 : /*
3632 : * Kill the pid if it's still here. If not, that's what we
3633 : * wanted so ignore any errors.
3634 : */
3635 18 : (void) SendProcSignal(pid, sigmode, procvxid.procNumber);
3636 : }
3637 : }
3638 : }
3639 :
3640 18 : LWLockRelease(ProcArrayLock);
3641 18 : }
3642 :
3643 : /*
3644 : * CountUserBackends --- count backends that are used by specified user
3645 : * (only regular backends, not any type of background worker)
3646 : */
3647 : int
3648 0 : CountUserBackends(Oid roleid)
3649 : {
3650 0 : ProcArrayStruct *arrayP = procArray;
3651 0 : int count = 0;
3652 : int index;
3653 :
3654 0 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3655 :
3656 0 : for (index = 0; index < arrayP->numProcs; index++)
3657 : {
3658 0 : int pgprocno = arrayP->pgprocnos[index];
3659 0 : PGPROC *proc = &allProcs[pgprocno];
3660 :
3661 0 : if (proc->pid == 0)
3662 0 : continue; /* do not count prepared xacts */
3663 0 : if (proc->backendType != B_BACKEND)
3664 0 : continue; /* count only regular backend processes */
3665 0 : if (proc->roleId == roleid)
3666 0 : count++;
3667 : }
3668 :
3669 0 : LWLockRelease(ProcArrayLock);
3670 :
3671 0 : return count;
3672 : }
3673 :
3674 : /*
3675 : * CountOtherDBBackends -- check for other backends running in the given DB
3676 : *
3677 : * If there are other backends in the DB, we will wait a maximum of 5 seconds
3678 : * for them to exit (or 0.3s for testing purposes). Autovacuum backends are
3679 : * encouraged to exit early by sending them SIGTERM, but normal user backends
3680 : * are just waited for. If background workers connected to this database are
3681 : * marked as interruptible, they are terminated.
3682 : *
3683 : * The current backend is always ignored; it is caller's responsibility to
3684 : * check whether the current backend uses the given DB, if it's important.
3685 : *
3686 : * Returns true if there are (still) other backends in the DB, false if not.
3687 : * Also, *nbackends and *nprepared are set to the number of other backends
3688 : * and prepared transactions in the DB, respectively.
3689 : *
3690 : * This function is used to interlock DROP DATABASE and related commands
3691 : * against there being any active backends in the target DB --- dropping the
3692 : * DB while active backends remain would be a Bad Thing. Note that we cannot
3693 : * detect here the possibility of a newly-started backend that is trying to
3694 : * connect to the doomed database, so additional interlocking is needed during
3695 : * backend startup. The caller should normally hold an exclusive lock on the
3696 : * target DB before calling this, which is one reason we mustn't wait
3697 : * indefinitely.
3698 : */
3699 : bool
3700 920 : CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
3701 : {
3702 920 : ProcArrayStruct *arrayP = procArray;
3703 :
3704 : #define MAXAUTOVACPIDS 10 /* max autovacs to SIGTERM per iteration */
3705 : int autovac_pids[MAXAUTOVACPIDS];
3706 :
3707 : /*
3708 : * Retry up to 50 times with 100ms between attempts (max 5s total). Can be
3709 : * reduced to 3 attempts (max 0.3s total) to speed up tests.
3710 : */
3711 920 : int ntries = 50;
3712 :
3713 : #ifdef USE_INJECTION_POINTS
3714 920 : if (IS_INJECTION_POINT_ATTACHED("procarray-reduce-count"))
3715 2 : ntries = 3;
3716 : #endif
3717 :
3718 936 : for (int tries = 0; tries < ntries; tries++)
3719 : {
3720 934 : int nautovacs = 0;
3721 934 : bool found = false;
3722 : int index;
3723 :
3724 934 : CHECK_FOR_INTERRUPTS();
3725 :
3726 934 : *nbackends = *nprepared = 0;
3727 :
3728 934 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3729 :
3730 3458 : for (index = 0; index < arrayP->numProcs; index++)
3731 : {
3732 2524 : int pgprocno = arrayP->pgprocnos[index];
3733 2524 : PGPROC *proc = &allProcs[pgprocno];
3734 2524 : uint8 statusFlags = ProcGlobal->statusFlags[index];
3735 :
3736 2524 : if (proc->databaseId != databaseId)
3737 2302 : continue;
3738 222 : if (proc == MyProc)
3739 206 : continue;
3740 :
3741 16 : found = true;
3742 :
3743 16 : if (proc->pid == 0)
3744 0 : (*nprepared)++;
3745 : else
3746 : {
3747 16 : (*nbackends)++;
3748 16 : if ((statusFlags & PROC_IS_AUTOVACUUM) &&
3749 : nautovacs < MAXAUTOVACPIDS)
3750 0 : autovac_pids[nautovacs++] = proc->pid;
3751 : }
3752 : }
3753 :
3754 934 : LWLockRelease(ProcArrayLock);
3755 :
3756 934 : if (!found)
3757 918 : return false; /* no conflicting backends, so done */
3758 :
3759 : /*
3760 : * Send SIGTERM to any conflicting autovacuums before sleeping. We
3761 : * postpone this step until after the loop because we don't want to
3762 : * hold ProcArrayLock while issuing kill(). We have no idea what might
3763 : * block kill() inside the kernel...
3764 : */
3765 16 : for (index = 0; index < nautovacs; index++)
3766 0 : (void) kill(autovac_pids[index], SIGTERM); /* ignore any error */
3767 :
3768 : /*
3769 : * Terminate all background workers for this database, if they have
3770 : * requested it (BGWORKER_INTERRUPTIBLE).
3771 : */
3772 16 : TerminateBackgroundWorkersForDatabase(databaseId);
3773 :
3774 : /* sleep, then try again */
3775 16 : pg_usleep(100 * 1000L); /* 100ms */
3776 : }
3777 :
3778 2 : return true; /* timed out, still conflicts */
3779 : }
3780 :
3781 : /*
3782 : * Terminate existing connections to the specified database. This routine
3783 : * is used by the DROP DATABASE command when user has asked to forcefully
3784 : * drop the database.
3785 : *
3786 : * The current backend is always ignored; it is caller's responsibility to
3787 : * check whether the current backend uses the given DB, if it's important.
3788 : *
3789 : * If the target database has a prepared transaction or permissions checks
3790 : * fail for a connection, this fails without terminating anything.
3791 : */
3792 : void
3793 2 : TerminateOtherDBBackends(Oid databaseId)
3794 : {
3795 2 : ProcArrayStruct *arrayP = procArray;
3796 2 : List *pids = NIL;
3797 2 : int nprepared = 0;
3798 : int i;
3799 :
3800 2 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3801 :
3802 8 : for (i = 0; i < procArray->numProcs; i++)
3803 : {
3804 6 : int pgprocno = arrayP->pgprocnos[i];
3805 6 : PGPROC *proc = &allProcs[pgprocno];
3806 :
3807 6 : if (proc->databaseId != databaseId)
3808 6 : continue;
3809 0 : if (proc == MyProc)
3810 0 : continue;
3811 :
3812 0 : if (proc->pid != 0)
3813 0 : pids = lappend_int(pids, proc->pid);
3814 : else
3815 0 : nprepared++;
3816 : }
3817 :
3818 2 : LWLockRelease(ProcArrayLock);
3819 :
3820 2 : if (nprepared > 0)
3821 0 : ereport(ERROR,
3822 : (errcode(ERRCODE_OBJECT_IN_USE),
3823 : errmsg("database \"%s\" is being used by prepared transactions",
3824 : get_database_name(databaseId)),
3825 : errdetail_plural("There is %d prepared transaction using the database.",
3826 : "There are %d prepared transactions using the database.",
3827 : nprepared,
3828 : nprepared)));
3829 :
3830 2 : if (pids)
3831 : {
3832 : ListCell *lc;
3833 :
3834 : /*
3835 : * Permissions checks relax the pg_terminate_backend checks in two
3836 : * ways, both by omitting the !OidIsValid(proc->roleId) check:
3837 : *
3838 : * - Accept terminating autovacuum workers, since DROP DATABASE
3839 : * without FORCE terminates them.
3840 : *
3841 : * - Accept terminating bgworkers. For bgworker authors, it's
3842 : * convenient to be able to recommend FORCE if a worker is blocking
3843 : * DROP DATABASE unexpectedly.
3844 : *
3845 : * Unlike pg_terminate_backend, we don't raise some warnings - like
3846 : * "PID %d is not a PostgreSQL server process", because for us already
3847 : * finished session is not a problem.
3848 : */
3849 0 : foreach(lc, pids)
3850 : {
3851 0 : int pid = lfirst_int(lc);
3852 0 : PGPROC *proc = BackendPidGetProc(pid);
3853 :
3854 0 : if (proc != NULL)
3855 : {
3856 0 : if (superuser_arg(proc->roleId) && !superuser())
3857 0 : ereport(ERROR,
3858 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3859 : errmsg("permission denied to terminate process"),
3860 : errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
3861 : "SUPERUSER", "SUPERUSER")));
3862 :
3863 0 : if (!has_privs_of_role(GetUserId(), proc->roleId) &&
3864 0 : !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
3865 0 : ereport(ERROR,
3866 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3867 : errmsg("permission denied to terminate process"),
3868 : errdetail("Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
3869 : "pg_signal_backend")));
3870 : }
3871 : }
3872 :
3873 : /*
3874 : * There's a race condition here: once we release the ProcArrayLock,
3875 : * it's possible for the session to exit before we issue kill. That
3876 : * race condition possibility seems too unlikely to worry about. See
3877 : * pg_signal_backend.
3878 : */
3879 0 : foreach(lc, pids)
3880 : {
3881 0 : int pid = lfirst_int(lc);
3882 0 : PGPROC *proc = BackendPidGetProc(pid);
3883 :
3884 0 : if (proc != NULL)
3885 : {
3886 : /*
3887 : * If we have setsid(), signal the backend's whole process
3888 : * group
3889 : */
3890 : #ifdef HAVE_SETSID
3891 0 : (void) kill(-pid, SIGTERM);
3892 : #else
3893 : (void) kill(pid, SIGTERM);
3894 : #endif
3895 : }
3896 : }
3897 : }
3898 2 : }
3899 :
3900 : /*
3901 : * ProcArraySetReplicationSlotXmin
3902 : *
3903 : * Install limits to future computations of the xmin horizon to prevent vacuum
3904 : * and HOT pruning from removing affected rows still needed by clients with
3905 : * replication slots.
3906 : */
3907 : void
3908 4880 : ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin,
3909 : bool already_locked)
3910 : {
3911 : Assert(!already_locked || LWLockHeldByMe(ProcArrayLock));
3912 :
3913 4880 : if (!already_locked)
3914 3908 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
3915 :
3916 4880 : procArray->replication_slot_xmin = xmin;
3917 4880 : procArray->replication_slot_catalog_xmin = catalog_xmin;
3918 :
3919 4880 : if (!already_locked)
3920 3908 : LWLockRelease(ProcArrayLock);
3921 :
3922 4880 : elog(DEBUG1, "xmin required by slots: data %u, catalog %u",
3923 : xmin, catalog_xmin);
3924 4880 : }
3925 :
3926 : /*
3927 : * ProcArrayGetReplicationSlotXmin
3928 : *
3929 : * Return the current slot xmin limits. That's useful to be able to remove
3930 : * data that's older than those limits.
3931 : */
3932 : void
3933 44 : ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
3934 : TransactionId *catalog_xmin)
3935 : {
3936 44 : LWLockAcquire(ProcArrayLock, LW_SHARED);
3937 :
3938 44 : if (xmin != NULL)
3939 0 : *xmin = procArray->replication_slot_xmin;
3940 :
3941 44 : if (catalog_xmin != NULL)
3942 44 : *catalog_xmin = procArray->replication_slot_catalog_xmin;
3943 :
3944 44 : LWLockRelease(ProcArrayLock);
3945 44 : }
3946 :
3947 : /*
3948 : * XidCacheRemoveRunningXids
3949 : *
3950 : * Remove a bunch of TransactionIds from the list of known-running
3951 : * subtransactions for my backend. Both the specified xid and those in
3952 : * the xids[] array (of length nxids) are removed from the subxids cache.
3953 : * latestXid must be the latest XID among the group.
3954 : */
3955 : void
3956 1334 : XidCacheRemoveRunningXids(TransactionId xid,
3957 : int nxids, const TransactionId *xids,
3958 : TransactionId latestXid)
3959 : {
3960 : int i,
3961 : j;
3962 : XidCacheStatus *mysubxidstat;
3963 :
3964 : Assert(TransactionIdIsValid(xid));
3965 :
3966 : /*
3967 : * We must hold ProcArrayLock exclusively in order to remove transactions
3968 : * from the PGPROC array. (See src/backend/access/transam/README.) It's
3969 : * possible this could be relaxed since we know this routine is only used
3970 : * to abort subtransactions, but pending closer analysis we'd best be
3971 : * conservative.
3972 : *
3973 : * Note that we do not have to be careful about memory ordering of our own
3974 : * reads wrt. GetNewTransactionId() here - only this process can modify
3975 : * relevant fields of MyProc/ProcGlobal->xids[]. But we do have to be
3976 : * careful about our own writes being well ordered.
3977 : */
3978 1334 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
3979 :
3980 1334 : mysubxidstat = &ProcGlobal->subxidStates[MyProc->pgxactoff];
3981 :
3982 : /*
3983 : * Under normal circumstances xid and xids[] will be in increasing order,
3984 : * as will be the entries in subxids. Scan backwards to avoid O(N^2)
3985 : * behavior when removing a lot of xids.
3986 : */
3987 1394 : for (i = nxids - 1; i >= 0; i--)
3988 : {
3989 60 : TransactionId anxid = xids[i];
3990 :
3991 60 : for (j = MyProc->subxidStatus.count - 1; j >= 0; j--)
3992 : {
3993 60 : if (TransactionIdEquals(MyProc->subxids.xids[j], anxid))
3994 : {
3995 60 : MyProc->subxids.xids[j] = MyProc->subxids.xids[MyProc->subxidStatus.count - 1];
3996 60 : pg_write_barrier();
3997 60 : mysubxidstat->count--;
3998 60 : MyProc->subxidStatus.count--;
3999 60 : break;
4000 : }
4001 : }
4002 :
4003 : /*
4004 : * Ordinarily we should have found it, unless the cache has
4005 : * overflowed. However it's also possible for this routine to be
4006 : * invoked multiple times for the same subtransaction, in case of an
4007 : * error during AbortSubTransaction. So instead of Assert, emit a
4008 : * debug warning.
4009 : */
4010 60 : if (j < 0 && !MyProc->subxidStatus.overflowed)
4011 0 : elog(WARNING, "did not find subXID %u in MyProc", anxid);
4012 : }
4013 :
4014 1462 : for (j = MyProc->subxidStatus.count - 1; j >= 0; j--)
4015 : {
4016 1460 : if (TransactionIdEquals(MyProc->subxids.xids[j], xid))
4017 : {
4018 1332 : MyProc->subxids.xids[j] = MyProc->subxids.xids[MyProc->subxidStatus.count - 1];
4019 1332 : pg_write_barrier();
4020 1332 : mysubxidstat->count--;
4021 1332 : MyProc->subxidStatus.count--;
4022 1332 : break;
4023 : }
4024 : }
4025 : /* Ordinarily we should have found it, unless the cache has overflowed */
4026 1334 : if (j < 0 && !MyProc->subxidStatus.overflowed)
4027 0 : elog(WARNING, "did not find subXID %u in MyProc", xid);
4028 :
4029 : /* Also advance global latestCompletedXid while holding the lock */
4030 1334 : MaintainLatestCompletedXid(latestXid);
4031 :
4032 : /* ... and xactCompletionCount */
4033 1334 : TransamVariables->xactCompletionCount++;
4034 :
4035 1334 : LWLockRelease(ProcArrayLock);
4036 1334 : }
4037 :
4038 : #ifdef XIDCACHE_DEBUG
4039 :
4040 : /*
4041 : * Print stats about effectiveness of XID cache
4042 : */
4043 : static void
4044 : DisplayXidCache(void)
4045 : {
4046 : fprintf(stderr,
4047 : "XidCache: xmin: %ld, known: %ld, myxact: %ld, latest: %ld, mainxid: %ld, childxid: %ld, knownassigned: %ld, nooflo: %ld, slow: %ld\n",
4048 : xc_by_recent_xmin,
4049 : xc_by_known_xact,
4050 : xc_by_my_xact,
4051 : xc_by_latest_xid,
4052 : xc_by_main_xid,
4053 : xc_by_child_xid,
4054 : xc_by_known_assigned,
4055 : xc_no_overflow,
4056 : xc_slow_answer);
4057 : }
4058 : #endif /* XIDCACHE_DEBUG */
4059 :
4060 : /*
4061 : * If rel != NULL, return test state appropriate for relation, otherwise
4062 : * return state usable for all relations. The latter may consider XIDs as
4063 : * not-yet-visible-to-everyone that a state for a specific relation would
4064 : * already consider visible-to-everyone.
4065 : *
4066 : * This needs to be called while a snapshot is active or registered, otherwise
4067 : * there are wraparound and other dangers.
4068 : *
4069 : * See comment for GlobalVisState for details.
4070 : */
4071 : GlobalVisState *
4072 28798350 : GlobalVisTestFor(Relation rel)
4073 : {
4074 28798350 : GlobalVisState *state = NULL;
4075 :
4076 : /* XXX: we should assert that a snapshot is pushed or registered */
4077 : Assert(RecentXmin);
4078 :
4079 28798350 : switch (GlobalVisHorizonKindForRel(rel))
4080 : {
4081 170136 : case VISHORIZON_SHARED:
4082 170136 : state = &GlobalVisSharedRels;
4083 170136 : break;
4084 5915624 : case VISHORIZON_CATALOG:
4085 5915624 : state = &GlobalVisCatalogRels;
4086 5915624 : break;
4087 22628670 : case VISHORIZON_DATA:
4088 22628670 : state = &GlobalVisDataRels;
4089 22628670 : break;
4090 83920 : case VISHORIZON_TEMP:
4091 83920 : state = &GlobalVisTempRels;
4092 83920 : break;
4093 : }
4094 :
4095 : Assert(FullTransactionIdIsValid(state->definitely_needed) &&
4096 : FullTransactionIdIsValid(state->maybe_needed));
4097 :
4098 28798350 : return state;
4099 : }
4100 :
4101 : /*
4102 : * Return true if it's worth updating the accurate maybe_needed boundary.
4103 : *
4104 : * As it is somewhat expensive to determine xmin horizons, we don't want to
4105 : * repeatedly do so when there is a low likelihood of it being beneficial.
4106 : *
4107 : * The current heuristic is that we update only if RecentXmin has changed
4108 : * since the last update. If the oldest currently running transaction has not
4109 : * finished, it is unlikely that recomputing the horizon would be useful.
4110 : */
4111 : static bool
4112 861372 : GlobalVisTestShouldUpdate(GlobalVisState *state)
4113 : {
4114 : /* hasn't been updated yet */
4115 861372 : if (!TransactionIdIsValid(ComputeXidHorizonsResultLastXmin))
4116 17482 : return true;
4117 :
4118 : /*
4119 : * If the maybe_needed/definitely_needed boundaries are the same, it's
4120 : * unlikely to be beneficial to refresh boundaries.
4121 : */
4122 843890 : if (FullTransactionIdFollowsOrEquals(state->maybe_needed,
4123 : state->definitely_needed))
4124 0 : return false;
4125 :
4126 : /* does the last snapshot built have a different xmin? */
4127 843890 : return RecentXmin != ComputeXidHorizonsResultLastXmin;
4128 : }
4129 :
4130 : static void
4131 360360 : GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons)
4132 : {
4133 : GlobalVisSharedRels.maybe_needed =
4134 360360 : FullXidRelativeTo(horizons->latest_completed,
4135 : horizons->shared_oldest_nonremovable);
4136 : GlobalVisCatalogRels.maybe_needed =
4137 360360 : FullXidRelativeTo(horizons->latest_completed,
4138 : horizons->catalog_oldest_nonremovable);
4139 : GlobalVisDataRels.maybe_needed =
4140 360360 : FullXidRelativeTo(horizons->latest_completed,
4141 : horizons->data_oldest_nonremovable);
4142 : GlobalVisTempRels.maybe_needed =
4143 360360 : FullXidRelativeTo(horizons->latest_completed,
4144 : horizons->temp_oldest_nonremovable);
4145 :
4146 : /*
4147 : * In longer running transactions it's possible that transactions we
4148 : * previously needed to treat as running aren't around anymore. So update
4149 : * definitely_needed to not be earlier than maybe_needed.
4150 : */
4151 : GlobalVisSharedRels.definitely_needed =
4152 360360 : FullTransactionIdNewer(GlobalVisSharedRels.maybe_needed,
4153 : GlobalVisSharedRels.definitely_needed);
4154 : GlobalVisCatalogRels.definitely_needed =
4155 360360 : FullTransactionIdNewer(GlobalVisCatalogRels.maybe_needed,
4156 : GlobalVisCatalogRels.definitely_needed);
4157 : GlobalVisDataRels.definitely_needed =
4158 360360 : FullTransactionIdNewer(GlobalVisDataRels.maybe_needed,
4159 : GlobalVisDataRels.definitely_needed);
4160 360360 : GlobalVisTempRels.definitely_needed = GlobalVisTempRels.maybe_needed;
4161 :
4162 360360 : ComputeXidHorizonsResultLastXmin = RecentXmin;
4163 360360 : }
4164 :
4165 : /*
4166 : * Update boundaries in GlobalVis{Shared,Catalog, Data}Rels
4167 : * using ComputeXidHorizons().
4168 : */
4169 : static void
4170 106216 : GlobalVisUpdate(void)
4171 : {
4172 : ComputeXidHorizonsResult horizons;
4173 :
4174 : /* updates the horizons as a side-effect */
4175 106216 : ComputeXidHorizons(&horizons);
4176 106216 : }
4177 :
4178 : /*
4179 : * Return true if no snapshot still considers fxid to be running.
4180 : *
4181 : * The state passed needs to have been initialized for the relation fxid is
4182 : * from (NULL is also OK), otherwise the result may not be correct.
4183 : *
4184 : * See comment for GlobalVisState for details.
4185 : */
4186 : bool
4187 19287194 : GlobalVisTestIsRemovableFullXid(GlobalVisState *state,
4188 : FullTransactionId fxid)
4189 : {
4190 : /*
4191 : * If fxid is older than maybe_needed bound, it definitely is visible to
4192 : * everyone.
4193 : */
4194 19287194 : if (FullTransactionIdPrecedes(fxid, state->maybe_needed))
4195 4795112 : return true;
4196 :
4197 : /*
4198 : * If fxid is >= definitely_needed bound, it is very likely to still be
4199 : * considered running.
4200 : */
4201 14492082 : if (FullTransactionIdFollowsOrEquals(fxid, state->definitely_needed))
4202 13630710 : return false;
4203 :
4204 : /*
4205 : * fxid is between maybe_needed and definitely_needed, i.e. there might or
4206 : * might not exist a snapshot considering fxid running. If it makes sense,
4207 : * update boundaries and recheck.
4208 : */
4209 861372 : if (GlobalVisTestShouldUpdate(state))
4210 : {
4211 106216 : GlobalVisUpdate();
4212 :
4213 : Assert(FullTransactionIdPrecedes(fxid, state->definitely_needed));
4214 :
4215 106216 : return FullTransactionIdPrecedes(fxid, state->maybe_needed);
4216 : }
4217 : else
4218 755156 : return false;
4219 : }
4220 :
4221 : /*
4222 : * Wrapper around GlobalVisTestIsRemovableFullXid() for 32bit xids.
4223 : *
4224 : * It is crucial that this only gets called for xids from a source that
4225 : * protects against xid wraparounds (e.g. from a table and thus protected by
4226 : * relfrozenxid).
4227 : */
4228 : bool
4229 19284940 : GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid)
4230 : {
4231 : FullTransactionId fxid;
4232 :
4233 : /*
4234 : * Convert 32 bit argument to FullTransactionId. We can do so safely
4235 : * because we know the xid has to, at the very least, be between
4236 : * [oldestXid, nextXid), i.e. within 2 billion of xid. To avoid taking a
4237 : * lock to determine either, we can just compare with
4238 : * state->definitely_needed, which was based on those value at the time
4239 : * the current snapshot was built.
4240 : */
4241 19284940 : fxid = FullXidRelativeTo(state->definitely_needed, xid);
4242 :
4243 19284940 : return GlobalVisTestIsRemovableFullXid(state, fxid);
4244 : }
4245 :
4246 : /*
4247 : * Convenience wrapper around GlobalVisTestFor() and
4248 : * GlobalVisTestIsRemovableFullXid(), see their comments.
4249 : */
4250 : bool
4251 2254 : GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)
4252 : {
4253 : GlobalVisState *state;
4254 :
4255 2254 : state = GlobalVisTestFor(rel);
4256 :
4257 2254 : return GlobalVisTestIsRemovableFullXid(state, fxid);
4258 : }
4259 :
4260 : /*
4261 : * Convenience wrapper around GlobalVisTestFor() and
4262 : * GlobalVisTestIsRemovableXid(), see their comments.
4263 : */
4264 : bool
4265 16 : GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)
4266 : {
4267 : GlobalVisState *state;
4268 :
4269 16 : state = GlobalVisTestFor(rel);
4270 :
4271 16 : return GlobalVisTestIsRemovableXid(state, xid);
4272 : }
4273 :
4274 : /*
4275 : * Convert a 32 bit transaction id into 64 bit transaction id, by assuming it
4276 : * is within MaxTransactionId / 2 of XidFromFullTransactionId(rel).
4277 : *
4278 : * Be very careful about when to use this function. It can only safely be used
4279 : * when there is a guarantee that xid is within MaxTransactionId / 2 xids of
4280 : * rel. That e.g. can be guaranteed if the caller assures a snapshot is
4281 : * held by the backend and xid is from a table (where vacuum/freezing ensures
4282 : * the xid has to be within that range), or if xid is from the procarray and
4283 : * prevents xid wraparound that way.
4284 : */
4285 : static inline FullTransactionId
4286 23505544 : FullXidRelativeTo(FullTransactionId rel, TransactionId xid)
4287 : {
4288 23505544 : TransactionId rel_xid = XidFromFullTransactionId(rel);
4289 :
4290 : Assert(TransactionIdIsValid(xid));
4291 : Assert(TransactionIdIsValid(rel_xid));
4292 :
4293 : /* not guaranteed to find issues, but likely to catch mistakes */
4294 : AssertTransactionIdInAllowableRange(xid);
4295 :
4296 47011088 : return FullTransactionIdFromU64(U64FromFullTransactionId(rel)
4297 23505544 : + (int32) (xid - rel_xid));
4298 : }
4299 :
4300 :
4301 : /* ----------------------------------------------
4302 : * KnownAssignedTransactionIds sub-module
4303 : * ----------------------------------------------
4304 : */
4305 :
4306 : /*
4307 : * In Hot Standby mode, we maintain a list of transactions that are (or were)
4308 : * running on the primary at the current point in WAL. These XIDs must be
4309 : * treated as running by standby transactions, even though they are not in
4310 : * the standby server's PGPROC array.
4311 : *
4312 : * We record all XIDs that we know have been assigned. That includes all the
4313 : * XIDs seen in WAL records, plus all unobserved XIDs that we can deduce have
4314 : * been assigned. We can deduce the existence of unobserved XIDs because we
4315 : * know XIDs are assigned in sequence, with no gaps. The KnownAssignedXids
4316 : * list expands as new XIDs are observed or inferred, and contracts when
4317 : * transaction completion records arrive.
4318 : *
4319 : * During hot standby we do not fret too much about the distinction between
4320 : * top-level XIDs and subtransaction XIDs. We store both together in the
4321 : * KnownAssignedXids list. In backends, this is copied into snapshots in
4322 : * GetSnapshotData(), taking advantage of the fact that XidInMVCCSnapshot()
4323 : * doesn't care about the distinction either. Subtransaction XIDs are
4324 : * effectively treated as top-level XIDs and in the typical case pg_subtrans
4325 : * links are *not* maintained (which does not affect visibility).
4326 : *
4327 : * We have room in KnownAssignedXids and in snapshots to hold maxProcs *
4328 : * (1 + PGPROC_MAX_CACHED_SUBXIDS) XIDs, so every primary transaction must
4329 : * report its subtransaction XIDs in a WAL XLOG_XACT_ASSIGNMENT record at
4330 : * least every PGPROC_MAX_CACHED_SUBXIDS. When we receive one of these
4331 : * records, we mark the subXIDs as children of the top XID in pg_subtrans,
4332 : * and then remove them from KnownAssignedXids. This prevents overflow of
4333 : * KnownAssignedXids and snapshots, at the cost that status checks for these
4334 : * subXIDs will take a slower path through TransactionIdIsInProgress().
4335 : * This means that KnownAssignedXids is not necessarily complete for subXIDs,
4336 : * though it should be complete for top-level XIDs; this is the same situation
4337 : * that holds with respect to the PGPROC entries in normal running.
4338 : *
4339 : * When we throw away subXIDs from KnownAssignedXids, we need to keep track of
4340 : * that, similarly to tracking overflow of a PGPROC's subxids array. We do
4341 : * that by remembering the lastOverflowedXid, ie the last thrown-away subXID.
4342 : * As long as that is within the range of interesting XIDs, we have to assume
4343 : * that subXIDs are missing from snapshots. (Note that subXID overflow occurs
4344 : * on primary when 65th subXID arrives, whereas on standby it occurs when 64th
4345 : * subXID arrives - that is not an error.)
4346 : *
4347 : * Should a backend on primary somehow disappear before it can write an abort
4348 : * record, then we just leave those XIDs in KnownAssignedXids. They actually
4349 : * aborted but we think they were running; the distinction is irrelevant
4350 : * because either way any changes done by the transaction are not visible to
4351 : * backends in the standby. We prune KnownAssignedXids when
4352 : * XLOG_RUNNING_XACTS arrives, to forestall possible overflow of the
4353 : * array due to such dead XIDs.
4354 : */
4355 :
4356 : /*
4357 : * RecordKnownAssignedTransactionIds
4358 : * Record the given XID in KnownAssignedXids, as well as any preceding
4359 : * unobserved XIDs.
4360 : *
4361 : * RecordKnownAssignedTransactionIds() should be run for *every* WAL record
4362 : * associated with a transaction. Must be called for each record after we
4363 : * have executed StartupCLOG() et al, since we must ExtendCLOG() etc..
4364 : *
4365 : * Called during recovery in analogy with and in place of GetNewTransactionId()
4366 : */
4367 : void
4368 5024294 : RecordKnownAssignedTransactionIds(TransactionId xid)
4369 : {
4370 : Assert(standbyState >= STANDBY_INITIALIZED);
4371 : Assert(TransactionIdIsValid(xid));
4372 : Assert(TransactionIdIsValid(latestObservedXid));
4373 :
4374 5024294 : elog(DEBUG4, "record known xact %u latestObservedXid %u",
4375 : xid, latestObservedXid);
4376 :
4377 : /*
4378 : * When a newly observed xid arrives, it is frequently the case that it is
4379 : * *not* the next xid in sequence. When this occurs, we must treat the
4380 : * intervening xids as running also.
4381 : */
4382 5024294 : if (TransactionIdFollows(xid, latestObservedXid))
4383 : {
4384 : TransactionId next_expected_xid;
4385 :
4386 : /*
4387 : * Extend subtrans like we do in GetNewTransactionId() during normal
4388 : * operation using individual extend steps. Note that we do not need
4389 : * to extend clog since its extensions are WAL logged.
4390 : *
4391 : * This part has to be done regardless of standbyState since we
4392 : * immediately start assigning subtransactions to their toplevel
4393 : * transactions.
4394 : */
4395 46146 : next_expected_xid = latestObservedXid;
4396 93794 : while (TransactionIdPrecedes(next_expected_xid, xid))
4397 : {
4398 47648 : TransactionIdAdvance(next_expected_xid);
4399 47648 : ExtendSUBTRANS(next_expected_xid);
4400 : }
4401 : Assert(next_expected_xid == xid);
4402 :
4403 : /*
4404 : * If the KnownAssignedXids machinery isn't up yet, there's nothing
4405 : * more to do since we don't track assigned xids yet.
4406 : */
4407 46146 : if (standbyState <= STANDBY_INITIALIZED)
4408 : {
4409 0 : latestObservedXid = xid;
4410 0 : return;
4411 : }
4412 :
4413 : /*
4414 : * Add (latestObservedXid, xid] onto the KnownAssignedXids array.
4415 : */
4416 46146 : next_expected_xid = latestObservedXid;
4417 46146 : TransactionIdAdvance(next_expected_xid);
4418 46146 : KnownAssignedXidsAdd(next_expected_xid, xid, false);
4419 :
4420 : /*
4421 : * Now we can advance latestObservedXid
4422 : */
4423 46146 : latestObservedXid = xid;
4424 :
4425 : /* TransamVariables->nextXid must be beyond any observed xid */
4426 46146 : AdvanceNextFullTransactionIdPastXid(latestObservedXid);
4427 : }
4428 : }
4429 :
4430 : /*
4431 : * ExpireTreeKnownAssignedTransactionIds
4432 : * Remove the given XIDs from KnownAssignedXids.
4433 : *
4434 : * Called during recovery in analogy with and in place of ProcArrayEndTransaction()
4435 : */
4436 : void
4437 44580 : ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
4438 : TransactionId *subxids, TransactionId max_xid)
4439 : {
4440 : Assert(standbyState >= STANDBY_INITIALIZED);
4441 :
4442 : /*
4443 : * Uses same locking as transaction commit
4444 : */
4445 44580 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
4446 :
4447 44580 : KnownAssignedXidsRemoveTree(xid, nsubxids, subxids);
4448 :
4449 : /* As in ProcArrayEndTransaction, advance latestCompletedXid */
4450 44580 : MaintainLatestCompletedXidRecovery(max_xid);
4451 :
4452 : /* ... and xactCompletionCount */
4453 44580 : TransamVariables->xactCompletionCount++;
4454 :
4455 44580 : LWLockRelease(ProcArrayLock);
4456 44580 : }
4457 :
4458 : /*
4459 : * ExpireAllKnownAssignedTransactionIds
4460 : * Remove all entries in KnownAssignedXids and reset lastOverflowedXid.
4461 : */
4462 : void
4463 232 : ExpireAllKnownAssignedTransactionIds(void)
4464 : {
4465 : FullTransactionId latestXid;
4466 :
4467 232 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
4468 232 : KnownAssignedXidsRemovePreceding(InvalidTransactionId);
4469 :
4470 : /* Reset latestCompletedXid to nextXid - 1 */
4471 : Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
4472 232 : latestXid = TransamVariables->nextXid;
4473 232 : FullTransactionIdRetreat(&latestXid);
4474 232 : TransamVariables->latestCompletedXid = latestXid;
4475 :
4476 : /*
4477 : * Any transactions that were in-progress were effectively aborted, so
4478 : * advance xactCompletionCount.
4479 : */
4480 232 : TransamVariables->xactCompletionCount++;
4481 :
4482 : /*
4483 : * Reset lastOverflowedXid. Currently, lastOverflowedXid has no use after
4484 : * the call of this function. But do this for unification with what
4485 : * ExpireOldKnownAssignedTransactionIds() do.
4486 : */
4487 232 : procArray->lastOverflowedXid = InvalidTransactionId;
4488 232 : LWLockRelease(ProcArrayLock);
4489 232 : }
4490 :
4491 : /*
4492 : * ExpireOldKnownAssignedTransactionIds
4493 : * Remove KnownAssignedXids entries preceding the given XID and
4494 : * potentially reset lastOverflowedXid.
4495 : */
4496 : void
4497 1676 : ExpireOldKnownAssignedTransactionIds(TransactionId xid)
4498 : {
4499 : TransactionId latestXid;
4500 :
4501 1676 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
4502 :
4503 : /* As in ProcArrayEndTransaction, advance latestCompletedXid */
4504 1676 : latestXid = xid;
4505 1676 : TransactionIdRetreat(latestXid);
4506 1676 : MaintainLatestCompletedXidRecovery(latestXid);
4507 :
4508 : /* ... and xactCompletionCount */
4509 1676 : TransamVariables->xactCompletionCount++;
4510 :
4511 : /*
4512 : * Reset lastOverflowedXid if we know all transactions that have been
4513 : * possibly running are being gone. Not doing so could cause an incorrect
4514 : * lastOverflowedXid value, which makes extra snapshots be marked as
4515 : * suboverflowed.
4516 : */
4517 1676 : if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
4518 1664 : procArray->lastOverflowedXid = InvalidTransactionId;
4519 1676 : KnownAssignedXidsRemovePreceding(xid);
4520 1676 : LWLockRelease(ProcArrayLock);
4521 1676 : }
4522 :
4523 : /*
4524 : * KnownAssignedTransactionIdsIdleMaintenance
4525 : * Opportunistically do maintenance work when the startup process
4526 : * is about to go idle.
4527 : */
4528 : void
4529 8710 : KnownAssignedTransactionIdsIdleMaintenance(void)
4530 : {
4531 8710 : KnownAssignedXidsCompress(KAX_STARTUP_PROCESS_IDLE, false);
4532 8710 : }
4533 :
4534 :
4535 : /*
4536 : * Private module functions to manipulate KnownAssignedXids
4537 : *
4538 : * There are 5 main uses of the KnownAssignedXids data structure:
4539 : *
4540 : * * backends taking snapshots - all valid XIDs need to be copied out
4541 : * * backends seeking to determine presence of a specific XID
4542 : * * startup process adding new known-assigned XIDs
4543 : * * startup process removing specific XIDs as transactions end
4544 : * * startup process pruning array when special WAL records arrive
4545 : *
4546 : * This data structure is known to be a hot spot during Hot Standby, so we
4547 : * go to some lengths to make these operations as efficient and as concurrent
4548 : * as possible.
4549 : *
4550 : * The XIDs are stored in an array in sorted order --- TransactionIdPrecedes
4551 : * order, to be exact --- to allow binary search for specific XIDs. Note:
4552 : * in general TransactionIdPrecedes would not provide a total order, but
4553 : * we know that the entries present at any instant should not extend across
4554 : * a large enough fraction of XID space to wrap around (the primary would
4555 : * shut down for fear of XID wrap long before that happens). So it's OK to
4556 : * use TransactionIdPrecedes as a binary-search comparator.
4557 : *
4558 : * It's cheap to maintain the sortedness during insertions, since new known
4559 : * XIDs are always reported in XID order; we just append them at the right.
4560 : *
4561 : * To keep individual deletions cheap, we need to allow gaps in the array.
4562 : * This is implemented by marking array elements as valid or invalid using
4563 : * the parallel boolean array KnownAssignedXidsValid[]. A deletion is done
4564 : * by setting KnownAssignedXidsValid[i] to false, *without* clearing the
4565 : * XID entry itself. This preserves the property that the XID entries are
4566 : * sorted, so we can do binary searches easily. Periodically we compress
4567 : * out the unused entries; that's much cheaper than having to compress the
4568 : * array immediately on every deletion.
4569 : *
4570 : * The actually valid items in KnownAssignedXids[] and KnownAssignedXidsValid[]
4571 : * are those with indexes tail <= i < head; items outside this subscript range
4572 : * have unspecified contents. When head reaches the end of the array, we
4573 : * force compression of unused entries rather than wrapping around, since
4574 : * allowing wraparound would greatly complicate the search logic. We maintain
4575 : * an explicit tail pointer so that pruning of old XIDs can be done without
4576 : * immediately moving the array contents. In most cases only a small fraction
4577 : * of the array contains valid entries at any instant.
4578 : *
4579 : * Although only the startup process can ever change the KnownAssignedXids
4580 : * data structure, we still need interlocking so that standby backends will
4581 : * not observe invalid intermediate states. The convention is that backends
4582 : * must hold shared ProcArrayLock to examine the array. To remove XIDs from
4583 : * the array, the startup process must hold ProcArrayLock exclusively, for
4584 : * the usual transactional reasons (compare commit/abort of a transaction
4585 : * during normal running). Compressing unused entries out of the array
4586 : * likewise requires exclusive lock. To add XIDs to the array, we just insert
4587 : * them into slots to the right of the head pointer and then advance the head
4588 : * pointer. This doesn't require any lock at all, but on machines with weak
4589 : * memory ordering, we need to be careful that other processors see the array
4590 : * element changes before they see the head pointer change. We handle this by
4591 : * using memory barriers when reading or writing the head/tail pointers (unless
4592 : * the caller holds ProcArrayLock exclusively).
4593 : *
4594 : * Algorithmic analysis:
4595 : *
4596 : * If we have a maximum of M slots, with N XIDs currently spread across
4597 : * S elements then we have N <= S <= M always.
4598 : *
4599 : * * Adding a new XID is O(1) and needs no lock (unless compression must
4600 : * happen)
4601 : * * Compressing the array is O(S) and requires exclusive lock
4602 : * * Removing an XID is O(logS) and requires exclusive lock
4603 : * * Taking a snapshot is O(S) and requires shared lock
4604 : * * Checking for an XID is O(logS) and requires shared lock
4605 : *
4606 : * In comparison, using a hash table for KnownAssignedXids would mean that
4607 : * taking snapshots would be O(M). If we can maintain S << M then the
4608 : * sorted array technique will deliver significantly faster snapshots.
4609 : * If we try to keep S too small then we will spend too much time compressing,
4610 : * so there is an optimal point for any workload mix. We use a heuristic to
4611 : * decide when to compress the array, though trimming also helps reduce
4612 : * frequency of compressing. The heuristic requires us to track the number of
4613 : * currently valid XIDs in the array (N). Except in special cases, we'll
4614 : * compress when S >= 2N. Bounding S at 2N in turn bounds the time for
4615 : * taking a snapshot to be O(N), which it would have to be anyway.
4616 : */
4617 :
4618 :
4619 : /*
4620 : * Compress KnownAssignedXids by shifting valid data down to the start of the
4621 : * array, removing any gaps.
4622 : *
4623 : * A compression step is forced if "reason" is KAX_NO_SPACE, otherwise
4624 : * we do it only if a heuristic indicates it's a good time to do it.
4625 : *
4626 : * Compression requires holding ProcArrayLock in exclusive mode.
4627 : * Caller must pass haveLock = true if it already holds the lock.
4628 : */
4629 : static void
4630 55008 : KnownAssignedXidsCompress(KAXCompressReason reason, bool haveLock)
4631 : {
4632 55008 : ProcArrayStruct *pArray = procArray;
4633 : int head,
4634 : tail,
4635 : nelements;
4636 : int compress_index;
4637 : int i;
4638 :
4639 : /* Counters for compression heuristics */
4640 : static unsigned int transactionEndsCounter;
4641 : static TimestampTz lastCompressTs;
4642 :
4643 : /* Tuning constants */
4644 : #define KAX_COMPRESS_FREQUENCY 128 /* in transactions */
4645 : #define KAX_COMPRESS_IDLE_INTERVAL 1000 /* in ms */
4646 :
4647 : /*
4648 : * Since only the startup process modifies the head/tail pointers, we
4649 : * don't need a lock to read them here.
4650 : */
4651 55008 : head = pArray->headKnownAssignedXids;
4652 55008 : tail = pArray->tailKnownAssignedXids;
4653 55008 : nelements = head - tail;
4654 :
4655 : /*
4656 : * If we can choose whether to compress, use a heuristic to avoid
4657 : * compressing too often or not often enough. "Compress" here simply
4658 : * means moving the values to the beginning of the array, so it is not as
4659 : * complex or costly as typical data compression algorithms.
4660 : */
4661 55008 : if (nelements == pArray->numKnownAssignedXids)
4662 : {
4663 : /*
4664 : * When there are no gaps between head and tail, don't bother to
4665 : * compress, except in the KAX_NO_SPACE case where we must compress to
4666 : * create some space after the head.
4667 : */
4668 23186 : if (reason != KAX_NO_SPACE)
4669 23186 : return;
4670 : }
4671 31822 : else if (reason == KAX_TRANSACTION_END)
4672 : {
4673 : /*
4674 : * Consider compressing only once every so many commits. Frequency
4675 : * determined by benchmarks.
4676 : */
4677 29348 : if ((transactionEndsCounter++) % KAX_COMPRESS_FREQUENCY != 0)
4678 29100 : return;
4679 :
4680 : /*
4681 : * Furthermore, compress only if the used part of the array is less
4682 : * than 50% full (see comments above).
4683 : */
4684 248 : if (nelements < 2 * pArray->numKnownAssignedXids)
4685 12 : return;
4686 : }
4687 2474 : else if (reason == KAX_STARTUP_PROCESS_IDLE)
4688 : {
4689 : /*
4690 : * We're about to go idle for lack of new WAL, so we might as well
4691 : * compress. But not too often, to avoid ProcArray lock contention
4692 : * with readers.
4693 : */
4694 2244 : if (lastCompressTs != 0)
4695 : {
4696 : TimestampTz compress_after;
4697 :
4698 2244 : compress_after = TimestampTzPlusMilliseconds(lastCompressTs,
4699 : KAX_COMPRESS_IDLE_INTERVAL);
4700 2244 : if (GetCurrentTimestamp() < compress_after)
4701 2100 : return;
4702 : }
4703 : }
4704 :
4705 : /* Need to compress, so get the lock if we don't have it. */
4706 610 : if (!haveLock)
4707 144 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
4708 :
4709 : /*
4710 : * We compress the array by reading the valid values from tail to head,
4711 : * re-aligning data to 0th element.
4712 : */
4713 610 : compress_index = 0;
4714 22294 : for (i = tail; i < head; i++)
4715 : {
4716 21684 : if (KnownAssignedXidsValid[i])
4717 : {
4718 2752 : KnownAssignedXids[compress_index] = KnownAssignedXids[i];
4719 2752 : KnownAssignedXidsValid[compress_index] = true;
4720 2752 : compress_index++;
4721 : }
4722 : }
4723 : Assert(compress_index == pArray->numKnownAssignedXids);
4724 :
4725 610 : pArray->tailKnownAssignedXids = 0;
4726 610 : pArray->headKnownAssignedXids = compress_index;
4727 :
4728 610 : if (!haveLock)
4729 144 : LWLockRelease(ProcArrayLock);
4730 :
4731 : /* Update timestamp for maintenance. No need to hold lock for this. */
4732 610 : lastCompressTs = GetCurrentTimestamp();
4733 : }
4734 :
4735 : /*
4736 : * Add xids into KnownAssignedXids at the head of the array.
4737 : *
4738 : * xids from from_xid to to_xid, inclusive, are added to the array.
4739 : *
4740 : * If exclusive_lock is true then caller already holds ProcArrayLock in
4741 : * exclusive mode, so we need no extra locking here. Else caller holds no
4742 : * lock, so we need to be sure we maintain sufficient interlocks against
4743 : * concurrent readers. (Only the startup process ever calls this, so no need
4744 : * to worry about concurrent writers.)
4745 : */
4746 : static void
4747 46154 : KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid,
4748 : bool exclusive_lock)
4749 : {
4750 46154 : ProcArrayStruct *pArray = procArray;
4751 : TransactionId next_xid;
4752 : int head,
4753 : tail;
4754 : int nxids;
4755 : int i;
4756 :
4757 : Assert(TransactionIdPrecedesOrEquals(from_xid, to_xid));
4758 :
4759 : /*
4760 : * Calculate how many array slots we'll need. Normally this is cheap; in
4761 : * the unusual case where the XIDs cross the wrap point, we do it the hard
4762 : * way.
4763 : */
4764 46154 : if (to_xid >= from_xid)
4765 46154 : nxids = to_xid - from_xid + 1;
4766 : else
4767 : {
4768 0 : nxids = 1;
4769 0 : next_xid = from_xid;
4770 0 : while (TransactionIdPrecedes(next_xid, to_xid))
4771 : {
4772 0 : nxids++;
4773 0 : TransactionIdAdvance(next_xid);
4774 : }
4775 : }
4776 :
4777 : /*
4778 : * Since only the startup process modifies the head/tail pointers, we
4779 : * don't need a lock to read them here.
4780 : */
4781 46154 : head = pArray->headKnownAssignedXids;
4782 46154 : tail = pArray->tailKnownAssignedXids;
4783 :
4784 : Assert(head >= 0 && head <= pArray->maxKnownAssignedXids);
4785 : Assert(tail >= 0 && tail < pArray->maxKnownAssignedXids);
4786 :
4787 : /*
4788 : * Verify that insertions occur in TransactionId sequence. Note that even
4789 : * if the last existing element is marked invalid, it must still have a
4790 : * correctly sequenced XID value.
4791 : */
4792 78168 : if (head > tail &&
4793 32014 : TransactionIdFollowsOrEquals(KnownAssignedXids[head - 1], from_xid))
4794 : {
4795 0 : KnownAssignedXidsDisplay(LOG);
4796 0 : elog(ERROR, "out-of-order XID insertion in KnownAssignedXids");
4797 : }
4798 :
4799 : /*
4800 : * If our xids won't fit in the remaining space, compress out free space
4801 : */
4802 46154 : if (head + nxids > pArray->maxKnownAssignedXids)
4803 : {
4804 0 : KnownAssignedXidsCompress(KAX_NO_SPACE, exclusive_lock);
4805 :
4806 0 : head = pArray->headKnownAssignedXids;
4807 : /* note: we no longer care about the tail pointer */
4808 :
4809 : /*
4810 : * If it still won't fit then we're out of memory
4811 : */
4812 0 : if (head + nxids > pArray->maxKnownAssignedXids)
4813 0 : elog(ERROR, "too many KnownAssignedXids");
4814 : }
4815 :
4816 : /* Now we can insert the xids into the space starting at head */
4817 46154 : next_xid = from_xid;
4818 93810 : for (i = 0; i < nxids; i++)
4819 : {
4820 47656 : KnownAssignedXids[head] = next_xid;
4821 47656 : KnownAssignedXidsValid[head] = true;
4822 47656 : TransactionIdAdvance(next_xid);
4823 47656 : head++;
4824 : }
4825 :
4826 : /* Adjust count of number of valid entries */
4827 46154 : pArray->numKnownAssignedXids += nxids;
4828 :
4829 : /*
4830 : * Now update the head pointer. We use a write barrier to ensure that
4831 : * other processors see the above array updates before they see the head
4832 : * pointer change. The barrier isn't required if we're holding
4833 : * ProcArrayLock exclusively.
4834 : */
4835 46154 : if (!exclusive_lock)
4836 46146 : pg_write_barrier();
4837 :
4838 46154 : pArray->headKnownAssignedXids = head;
4839 46154 : }
4840 :
4841 : /*
4842 : * KnownAssignedXidsSearch
4843 : *
4844 : * Searches KnownAssignedXids for a specific xid and optionally removes it.
4845 : * Returns true if it was found, false if not.
4846 : *
4847 : * Caller must hold ProcArrayLock in shared or exclusive mode.
4848 : * Exclusive lock must be held for remove = true.
4849 : */
4850 : static bool
4851 49924 : KnownAssignedXidsSearch(TransactionId xid, bool remove)
4852 : {
4853 49924 : ProcArrayStruct *pArray = procArray;
4854 : int first,
4855 : last;
4856 : int head;
4857 : int tail;
4858 49924 : int result_index = -1;
4859 :
4860 49924 : tail = pArray->tailKnownAssignedXids;
4861 49924 : head = pArray->headKnownAssignedXids;
4862 :
4863 : /*
4864 : * Only the startup process removes entries, so we don't need the read
4865 : * barrier in that case.
4866 : */
4867 49924 : if (!remove)
4868 2 : pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */
4869 :
4870 : /*
4871 : * Standard binary search. Note we can ignore the KnownAssignedXidsValid
4872 : * array here, since even invalid entries will contain sorted XIDs.
4873 : */
4874 49924 : first = tail;
4875 49924 : last = head - 1;
4876 178738 : while (first <= last)
4877 : {
4878 : int mid_index;
4879 : TransactionId mid_xid;
4880 :
4881 176362 : mid_index = (first + last) / 2;
4882 176362 : mid_xid = KnownAssignedXids[mid_index];
4883 :
4884 176362 : if (xid == mid_xid)
4885 : {
4886 47548 : result_index = mid_index;
4887 47548 : break;
4888 : }
4889 128814 : else if (TransactionIdPrecedes(xid, mid_xid))
4890 26744 : last = mid_index - 1;
4891 : else
4892 102070 : first = mid_index + 1;
4893 : }
4894 :
4895 49924 : if (result_index < 0)
4896 2376 : return false; /* not in array */
4897 :
4898 47548 : if (!KnownAssignedXidsValid[result_index])
4899 64 : return false; /* in array, but invalid */
4900 :
4901 47484 : if (remove)
4902 : {
4903 47484 : KnownAssignedXidsValid[result_index] = false;
4904 :
4905 47484 : pArray->numKnownAssignedXids--;
4906 : Assert(pArray->numKnownAssignedXids >= 0);
4907 :
4908 : /*
4909 : * If we're removing the tail element then advance tail pointer over
4910 : * any invalid elements. This will speed future searches.
4911 : */
4912 47484 : if (result_index == tail)
4913 : {
4914 16302 : tail++;
4915 28552 : while (tail < head && !KnownAssignedXidsValid[tail])
4916 12250 : tail++;
4917 16302 : if (tail >= head)
4918 : {
4919 : /* Array is empty, so we can reset both pointers */
4920 14120 : pArray->headKnownAssignedXids = 0;
4921 14120 : pArray->tailKnownAssignedXids = 0;
4922 : }
4923 : else
4924 : {
4925 2182 : pArray->tailKnownAssignedXids = tail;
4926 : }
4927 : }
4928 : }
4929 :
4930 47484 : return true;
4931 : }
4932 :
4933 : /*
4934 : * Is the specified XID present in KnownAssignedXids[]?
4935 : *
4936 : * Caller must hold ProcArrayLock in shared or exclusive mode.
4937 : */
4938 : static bool
4939 2 : KnownAssignedXidExists(TransactionId xid)
4940 : {
4941 : Assert(TransactionIdIsValid(xid));
4942 :
4943 2 : return KnownAssignedXidsSearch(xid, false);
4944 : }
4945 :
4946 : /*
4947 : * Remove the specified XID from KnownAssignedXids[].
4948 : *
4949 : * Caller must hold ProcArrayLock in exclusive mode.
4950 : */
4951 : static void
4952 49922 : KnownAssignedXidsRemove(TransactionId xid)
4953 : {
4954 : Assert(TransactionIdIsValid(xid));
4955 :
4956 49922 : elog(DEBUG4, "remove KnownAssignedXid %u", xid);
4957 :
4958 : /*
4959 : * Note: we cannot consider it an error to remove an XID that's not
4960 : * present. We intentionally remove subxact IDs while processing
4961 : * XLOG_XACT_ASSIGNMENT, to avoid array overflow. Then those XIDs will be
4962 : * removed again when the top-level xact commits or aborts.
4963 : *
4964 : * It might be possible to track such XIDs to distinguish this case from
4965 : * actual errors, but it would be complicated and probably not worth it.
4966 : * So, just ignore the search result.
4967 : */
4968 49922 : (void) KnownAssignedXidsSearch(xid, true);
4969 49922 : }
4970 :
4971 : /*
4972 : * KnownAssignedXidsRemoveTree
4973 : * Remove xid (if it's not InvalidTransactionId) and all the subxids.
4974 : *
4975 : * Caller must hold ProcArrayLock in exclusive mode.
4976 : */
4977 : static void
4978 44622 : KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
4979 : TransactionId *subxids)
4980 : {
4981 : int i;
4982 :
4983 44622 : if (TransactionIdIsValid(xid))
4984 44580 : KnownAssignedXidsRemove(xid);
4985 :
4986 49964 : for (i = 0; i < nsubxids; i++)
4987 5342 : KnownAssignedXidsRemove(subxids[i]);
4988 :
4989 : /* Opportunistically compress the array */
4990 44622 : KnownAssignedXidsCompress(KAX_TRANSACTION_END, true);
4991 44622 : }
4992 :
4993 : /*
4994 : * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
4995 : * then clear the whole table.
4996 : *
4997 : * Caller must hold ProcArrayLock in exclusive mode.
4998 : */
4999 : static void
5000 1908 : KnownAssignedXidsRemovePreceding(TransactionId removeXid)
5001 : {
5002 1908 : ProcArrayStruct *pArray = procArray;
5003 1908 : int count = 0;
5004 : int head,
5005 : tail,
5006 : i;
5007 :
5008 1908 : if (!TransactionIdIsValid(removeXid))
5009 : {
5010 232 : elog(DEBUG4, "removing all KnownAssignedXids");
5011 232 : pArray->numKnownAssignedXids = 0;
5012 232 : pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
5013 232 : return;
5014 : }
5015 :
5016 1676 : elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
5017 :
5018 : /*
5019 : * Mark entries invalid starting at the tail. Since array is sorted, we
5020 : * can stop as soon as we reach an entry >= removeXid.
5021 : */
5022 1676 : tail = pArray->tailKnownAssignedXids;
5023 1676 : head = pArray->headKnownAssignedXids;
5024 :
5025 1676 : for (i = tail; i < head; i++)
5026 : {
5027 428 : if (KnownAssignedXidsValid[i])
5028 : {
5029 428 : TransactionId knownXid = KnownAssignedXids[i];
5030 :
5031 428 : if (TransactionIdFollowsOrEquals(knownXid, removeXid))
5032 428 : break;
5033 :
5034 0 : if (!StandbyTransactionIdIsPrepared(knownXid))
5035 : {
5036 0 : KnownAssignedXidsValid[i] = false;
5037 0 : count++;
5038 : }
5039 : }
5040 : }
5041 :
5042 1676 : pArray->numKnownAssignedXids -= count;
5043 : Assert(pArray->numKnownAssignedXids >= 0);
5044 :
5045 : /*
5046 : * Advance the tail pointer if we've marked the tail item invalid.
5047 : */
5048 1676 : for (i = tail; i < head; i++)
5049 : {
5050 428 : if (KnownAssignedXidsValid[i])
5051 428 : break;
5052 : }
5053 1676 : if (i >= head)
5054 : {
5055 : /* Array is empty, so we can reset both pointers */
5056 1248 : pArray->headKnownAssignedXids = 0;
5057 1248 : pArray->tailKnownAssignedXids = 0;
5058 : }
5059 : else
5060 : {
5061 428 : pArray->tailKnownAssignedXids = i;
5062 : }
5063 :
5064 : /* Opportunistically compress the array */
5065 1676 : KnownAssignedXidsCompress(KAX_PRUNE, true);
5066 : }
5067 :
5068 : /*
5069 : * KnownAssignedXidsGet - Get an array of xids by scanning KnownAssignedXids.
5070 : * We filter out anything >= xmax.
5071 : *
5072 : * Returns the number of XIDs stored into xarray[]. Caller is responsible
5073 : * that array is large enough.
5074 : *
5075 : * Caller must hold ProcArrayLock in (at least) shared mode.
5076 : */
5077 : static int
5078 0 : KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax)
5079 : {
5080 0 : TransactionId xtmp = InvalidTransactionId;
5081 :
5082 0 : return KnownAssignedXidsGetAndSetXmin(xarray, &xtmp, xmax);
5083 : }
5084 :
5085 : /*
5086 : * KnownAssignedXidsGetAndSetXmin - as KnownAssignedXidsGet, plus
5087 : * we reduce *xmin to the lowest xid value seen if not already lower.
5088 : *
5089 : * Caller must hold ProcArrayLock in (at least) shared mode.
5090 : */
5091 : static int
5092 2970 : KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin,
5093 : TransactionId xmax)
5094 : {
5095 2970 : int count = 0;
5096 : int head,
5097 : tail;
5098 : int i;
5099 :
5100 : /*
5101 : * Fetch head just once, since it may change while we loop. We can stop
5102 : * once we reach the initially seen head, since we are certain that an xid
5103 : * cannot enter and then leave the array while we hold ProcArrayLock. We
5104 : * might miss newly-added xids, but they should be >= xmax so irrelevant
5105 : * anyway.
5106 : */
5107 2970 : tail = procArray->tailKnownAssignedXids;
5108 2970 : head = procArray->headKnownAssignedXids;
5109 :
5110 2970 : pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */
5111 :
5112 3014 : for (i = tail; i < head; i++)
5113 : {
5114 : /* Skip any gaps in the array */
5115 366 : if (KnownAssignedXidsValid[i])
5116 : {
5117 350 : TransactionId knownXid = KnownAssignedXids[i];
5118 :
5119 : /*
5120 : * Update xmin if required. Only the first XID need be checked,
5121 : * since the array is sorted.
5122 : */
5123 700 : if (count == 0 &&
5124 350 : TransactionIdPrecedes(knownXid, *xmin))
5125 28 : *xmin = knownXid;
5126 :
5127 : /*
5128 : * Filter out anything >= xmax, again relying on sorted property
5129 : * of array.
5130 : */
5131 700 : if (TransactionIdIsValid(xmax) &&
5132 350 : TransactionIdFollowsOrEquals(knownXid, xmax))
5133 322 : break;
5134 :
5135 : /* Add knownXid into output array */
5136 28 : xarray[count++] = knownXid;
5137 : }
5138 : }
5139 :
5140 2970 : return count;
5141 : }
5142 :
5143 : /*
5144 : * Get oldest XID in the KnownAssignedXids array, or InvalidTransactionId
5145 : * if nothing there.
5146 : */
5147 : static TransactionId
5148 700 : KnownAssignedXidsGetOldestXmin(void)
5149 : {
5150 : int head,
5151 : tail;
5152 : int i;
5153 :
5154 : /*
5155 : * Fetch head just once, since it may change while we loop.
5156 : */
5157 700 : tail = procArray->tailKnownAssignedXids;
5158 700 : head = procArray->headKnownAssignedXids;
5159 :
5160 700 : pg_read_barrier(); /* pairs with KnownAssignedXidsAdd */
5161 :
5162 700 : for (i = tail; i < head; i++)
5163 : {
5164 : /* Skip any gaps in the array */
5165 296 : if (KnownAssignedXidsValid[i])
5166 296 : return KnownAssignedXids[i];
5167 : }
5168 :
5169 404 : return InvalidTransactionId;
5170 : }
5171 :
5172 : /*
5173 : * Display KnownAssignedXids to provide debug trail
5174 : *
5175 : * Currently this is only called within startup process, so we need no
5176 : * special locking.
5177 : *
5178 : * Note this is pretty expensive, and much of the expense will be incurred
5179 : * even if the elog message will get discarded. It's not currently called
5180 : * in any performance-critical places, however, so no need to be tenser.
5181 : */
5182 : static void
5183 240 : KnownAssignedXidsDisplay(int trace_level)
5184 : {
5185 240 : ProcArrayStruct *pArray = procArray;
5186 : StringInfoData buf;
5187 : int head,
5188 : tail,
5189 : i;
5190 240 : int nxids = 0;
5191 :
5192 240 : tail = pArray->tailKnownAssignedXids;
5193 240 : head = pArray->headKnownAssignedXids;
5194 :
5195 240 : initStringInfo(&buf);
5196 :
5197 256 : for (i = tail; i < head; i++)
5198 : {
5199 16 : if (KnownAssignedXidsValid[i])
5200 : {
5201 16 : nxids++;
5202 16 : appendStringInfo(&buf, "[%d]=%u ", i, KnownAssignedXids[i]);
5203 : }
5204 : }
5205 :
5206 240 : elog(trace_level, "%d KnownAssignedXids (num=%d tail=%d head=%d) %s",
5207 : nxids,
5208 : pArray->numKnownAssignedXids,
5209 : pArray->tailKnownAssignedXids,
5210 : pArray->headKnownAssignedXids,
5211 : buf.data);
5212 :
5213 240 : pfree(buf.data);
5214 240 : }
5215 :
5216 : /*
5217 : * KnownAssignedXidsReset
5218 : * Resets KnownAssignedXids to be empty
5219 : */
5220 : static void
5221 0 : KnownAssignedXidsReset(void)
5222 : {
5223 0 : ProcArrayStruct *pArray = procArray;
5224 :
5225 0 : LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
5226 :
5227 0 : pArray->numKnownAssignedXids = 0;
5228 0 : pArray->tailKnownAssignedXids = 0;
5229 0 : pArray->headKnownAssignedXids = 0;
5230 :
5231 0 : LWLockRelease(ProcArrayLock);
5232 0 : }
|