Skip to content

Commit 33b6dd8

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 77c8892 commit 33b6dd8

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,6 +3482,12 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
34823482
LVRelStats vacrelstats;
34833483
ErrorContextCallback errcallback;
34843484

3485+
/*
3486+
* A parallel vacuum worker must have only PROC_IN_VACUUM flag since we
3487+
* don't support parallel vacuum for autovacuum as of now.
3488+
*/
3489+
Assert(MyPgXact->vacuumFlags == PROC_IN_VACUUM);
3490+
34853491
lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED,
34863492
false);
34873493
elevel = lvshared->elevel;

src/backend/storage/ipc/procarray.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,10 @@ ProcArrayInstallImportedXmin(TransactionId xmin,
18641864
* PGPROC of the transaction from which we imported the snapshot, rather than
18651865
* an XID.
18661866
*
1867+
* Note that this function also copies vacuumFlags from the source `proc` in
1868+
* order to avoid the case where MyPgXact's xmin needs to be skipped for
1869+
* computing xid horizon.
1870+
*
18671871
* Returns true if successful, false if source xact is no longer running.
18681872
*/
18691873
bool
@@ -1876,8 +1880,10 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
18761880
Assert(TransactionIdIsNormal(xmin));
18771881
Assert(proc != NULL);
18781882

1879-
/* Get lock so source xact can't end while we're doing this */
1880-
LWLockAcquire(ProcArrayLock, LW_SHARED);
1883+
/*
1884+
* Get an exclusive lock so that we can copy vacuumFlags from source proc.
1885+
*/
1886+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
18811887

18821888
pgxact = &allPgXact[proc->pgprocno];
18831889

@@ -1892,7 +1898,13 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
18921898
TransactionIdIsNormal(xid) &&
18931899
TransactionIdPrecedesOrEquals(xid, xmin))
18941900
{
1901+
/* Install xmin */
18951902
MyPgXact->xmin = TransactionXmin = xmin;
1903+
1904+
/* Flags being copied must be valid copy-able flags. */
1905+
Assert((pgxact->vacuumFlags & (~PROC_COPYABLE_FLAGS)) == 0);
1906+
MyPgXact->vacuumFlags = pgxact->vacuumFlags;
1907+
18961908
result = true;
18971909
}
18981910

src/include/storage/proc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ struct XidCache
6262
#define PROC_VACUUM_STATE_MASK \
6363
(PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND)
6464

65+
/*
66+
* Flags that are valid to copy from another proc, the parallel leader
67+
* process in practice. Currently, a flag that is set during parallel
68+
* vacuum is allowed.
69+
*/
70+
#define PROC_COPYABLE_FLAGS (PROC_IN_VACUUM)
71+
6572
/*
6673
* We allow a small number of "weak" relation locks (AccessShareLock,
6774
* RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure

0 commit comments

Comments
 (0)