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