Skip to content

Commit 0f0cfb4

Browse files
author
Amit Kapila
committed
Fix parallel operations that prevent oldest xmin from advancing.
While determining xid horizons, we skip over backends that are running Vacuum. We also ignore Create Index Concurrently, or Reindex Concurrently for the purposes of computing Xmin for Vacuum. But we were not setting the flags corresponding to these operations when they are performed in parallel which was preventing Xid horizon from advancing. The optimization related to skipping Create Index Concurrently, or Reindex Concurrently operations was implemented in PG-14 but the fix is the same for the Parallel Vacuum as well so back-patched till PG-13. Author: Masahiko Sawada Reviewed-by: Amit Kapila Backpatch-through: 13 Discussion: https://postgr.es/m/CAD21AoCLQqgM1sXh9BrDFq0uzd3RBFKi=Vfo6cjjKODm0Onr5w@mail.gmail.com
1 parent 0cd6d3b commit 0f0cfb4

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

src/backend/access/heap/vacuumlazy.c

+6
Original file line numberDiff line numberDiff line change
@@ -4159,6 +4159,12 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
41594159
LVRelState vacrel;
41604160
ErrorContextCallback errcallback;
41614161

4162+
/*
4163+
* A parallel vacuum worker must have only PROC_IN_VACUUM flag since we
4164+
* don't support parallel vacuum for autovacuum as of now.
4165+
*/
4166+
Assert(MyProc->statusFlags == PROC_IN_VACUUM);
4167+
41624168
lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED,
41634169
false);
41644170
elevel = lvshared->elevel;

src/backend/access/nbtree/nbtsort.c

+7
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,13 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
18081808
ResetUsage();
18091809
#endif /* BTREE_BUILD_STATS */
18101810

1811+
/*
1812+
* The only possible status flag that can be set to the parallel worker is
1813+
* PROC_IN_SAFE_IC.
1814+
*/
1815+
Assert((MyProc->statusFlags == 0) ||
1816+
(MyProc->statusFlags == PROC_IN_SAFE_IC));
1817+
18111818
/* Set debug_query_string for individual workers first */
18121819
sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true);
18131820
debug_query_string = sharedquery;

src/backend/storage/ipc/procarray.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,10 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
26382638
* PGPROC of the transaction from which we imported the snapshot, rather than
26392639
* an XID.
26402640
*
2641+
* Note that this function also copies statusFlags from the source `proc` in
2642+
* order to avoid the case where MyProc's xmin needs to be skipped for
2643+
* computing xid horizon.
2644+
*
26412645
* Returns true if successful, false if source xact is no longer running.
26422646
*/
26432647
bool
@@ -2649,8 +2653,10 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
26492653
Assert(TransactionIdIsNormal(xmin));
26502654
Assert(proc != NULL);
26512655

2652-
/* Get lock so source xact can't end while we're doing this */
2653-
LWLockAcquire(ProcArrayLock, LW_SHARED);
2656+
/*
2657+
* Get an exclusive lock so that we can copy statusFlags from source proc.
2658+
*/
2659+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
26542660

26552661
/*
26562662
* Be certain that the referenced PGPROC has an advertised xmin which is
@@ -2663,7 +2669,14 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
26632669
TransactionIdIsNormal(xid) &&
26642670
TransactionIdPrecedesOrEquals(xid, xmin))
26652671
{
2672+
/* Install xmin */
26662673
MyProc->xmin = TransactionXmin = xmin;
2674+
2675+
/* Flags being copied must be valid copy-able flags. */
2676+
Assert((proc->statusFlags & (~PROC_COPYABLE_FLAGS)) == 0);
2677+
MyProc->statusFlags = proc->statusFlags;
2678+
ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
2679+
26672680
result = true;
26682681
}
26692682

src/include/storage/proc.h

+7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ struct XidCache
6565
#define PROC_VACUUM_STATE_MASK \
6666
(PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND)
6767

68+
/*
69+
* Flags that are valid to copy from another proc, the parallel leader
70+
* process in practice. Currently, flags that are set during parallel
71+
* vacuum and parallel index creation are allowed.
72+
*/
73+
#define PROC_COPYABLE_FLAGS (PROC_IN_VACUUM | PROC_IN_SAFE_IC)
74+
6875
/*
6976
* We allow a small number of "weak" relation locks (AccessShareLock,
7077
* RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure

0 commit comments

Comments
 (0)