From af4b1a0869bd3bb52e5f662e4491554b7f611489 Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Wed, 22 Mar 2017 16:51:01 +0000 Subject: [PATCH] Refactor GetOldestXmin() to use flags Replace ignoreVacuum parameter with more flexible flags. Author: Eiji Seki Review: Haribabu Kommi --- contrib/pg_visibility/pg_visibility.c | 4 ++-- contrib/pgstattuple/pgstatapprox.c | 2 +- src/backend/access/transam/xlog.c | 4 ++-- src/backend/catalog/index.c | 2 +- src/backend/commands/analyze.c | 2 +- src/backend/commands/vacuum.c | 4 ++-- src/backend/replication/walreceiver.c | 2 +- src/backend/storage/ipc/procarray.c | 16 +++++----------- src/include/storage/proc.h | 7 ++++++- src/include/storage/procarray.h | 24 +++++++++++++++++++++++- 10 files changed, 44 insertions(+), 23 deletions(-) diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index d0f7618f62..ee3936e09a 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -557,7 +557,7 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen) if (all_visible) { /* Don't pass rel; that will fail in recovery. */ - OldestXmin = GetOldestXmin(NULL, true); + OldestXmin = GetOldestXmin(NULL, PROCARRAY_FLAGS_VACUUM); } rel = relation_open(relid, AccessShareLock); @@ -674,7 +674,7 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen) * a buffer lock. And this shouldn't happen often, so it's * worth being careful so as to avoid false positives. */ - RecomputedOldestXmin = GetOldestXmin(NULL, true); + RecomputedOldestXmin = GetOldestXmin(NULL, PROCARRAY_FLAGS_VACUUM); if (!TransactionIdPrecedes(OldestXmin, RecomputedOldestXmin)) record_corrupt_item(items, &tuple.t_self); diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c index 8db1e20373..46c167a96a 100644 --- a/contrib/pgstattuple/pgstatapprox.c +++ b/contrib/pgstattuple/pgstatapprox.c @@ -70,7 +70,7 @@ statapprox_heap(Relation rel, output_type *stat) TransactionId OldestXmin; uint64 misc_count = 0; - OldestXmin = GetOldestXmin(rel, true); + OldestXmin = GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM); bstrategy = GetAccessStrategy(BAS_BULKREAD); nblocks = RelationGetNumberOfBlocks(rel); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9480377611..ff4cf3a810 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -8895,7 +8895,7 @@ CreateCheckPoint(int flags) * StartupSUBTRANS hasn't been called yet. */ if (!RecoveryInProgress()) - TruncateSUBTRANS(GetOldestXmin(NULL, false)); + TruncateSUBTRANS(GetOldestXmin(NULL, PROCARRAY_FLAGS_DEFAULT)); /* Real work is done, but log and update stats before releasing lock. */ LogCheckpointEnd(false); @@ -9258,7 +9258,7 @@ CreateRestartPoint(int flags) * this because StartupSUBTRANS hasn't been called yet. */ if (EnableHotStandby) - TruncateSUBTRANS(GetOldestXmin(NULL, false)); + TruncateSUBTRANS(GetOldestXmin(NULL, PROCARRAY_FLAGS_DEFAULT)); /* Real work is done, but log and update before releasing lock. */ LogCheckpointEnd(true); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 8d42a347ea..7924c30369 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -2270,7 +2270,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, { snapshot = SnapshotAny; /* okay to ignore lazy VACUUMs here */ - OldestXmin = GetOldestXmin(heapRelation, true); + OldestXmin = GetOldestXmin(heapRelation, PROCARRAY_FLAGS_VACUUM); } scan = heap_beginscan_strat(heapRelation, /* relation */ diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index b91df986c5..055338fdff 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1000,7 +1000,7 @@ acquire_sample_rows(Relation onerel, int elevel, totalblocks = RelationGetNumberOfBlocks(onerel); /* Need a cutoff xmin for HeapTupleSatisfiesVacuum */ - OldestXmin = GetOldestXmin(onerel, true); + OldestXmin = GetOldestXmin(onerel, PROCARRAY_FLAGS_VACUUM); /* Prepare for sampling block numbers */ BlockSampler_Init(&bs, totalblocks, targrows, random()); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index ff633faca6..d8ae3e1e43 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -527,7 +527,7 @@ vacuum_set_xid_limits(Relation rel, * always an independent transaction. */ *oldestXmin = - TransactionIdLimitedForOldSnapshots(GetOldestXmin(rel, true), rel); + TransactionIdLimitedForOldSnapshots(GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM), rel); Assert(TransactionIdIsNormal(*oldestXmin)); @@ -939,7 +939,7 @@ vac_update_datfrozenxid(void) * committed pg_class entries for new tables; see AddNewRelationTuple(). * So we cannot produce a wrong minimum by starting with this. */ - newFrozenXid = GetOldestXmin(NULL, true); + newFrozenXid = GetOldestXmin(NULL, PROCARRAY_FLAGS_VACUUM); /* * Similarly, initialize the MultiXact "min" with the value that would be diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 18d9d7e4ec..31c567b37e 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -1221,7 +1221,7 @@ XLogWalRcvSendHSFeedback(bool immed) * everything else has been checked. */ if (hot_standby_feedback) - xmin = GetOldestXmin(NULL, false); + xmin = GetOldestXmin(NULL, PROCARRAY_FLAGS_DEFAULT); else xmin = InvalidTransactionId; diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 0f8f435faf..3e562d3a54 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1260,8 +1260,9 @@ TransactionIdIsActive(TransactionId xid) * If rel is NULL or a shared relation, all backends are considered, otherwise * only backends running in this database are considered. * - * If ignoreVacuum is TRUE then backends with the PROC_IN_VACUUM flag set are - * ignored. + * The flags are used to ignore the backends in calculation when any of the + * corresponding flags is set. Typically, if you want to ignore ones with + * PROC_IN_VACUUM flag, you can use PROCARRAY_FLAGS_VACUUM. * * This is used by VACUUM to decide which deleted tuples must be preserved in * the passed in table. For shared relations backends in all databases must be @@ -1302,7 +1303,7 @@ TransactionIdIsActive(TransactionId xid) * GetOldestXmin() move backwards, with no consequences for data integrity. */ TransactionId -GetOldestXmin(Relation rel, bool ignoreVacuum) +GetOldestXmin(Relation rel, int flags) { ProcArrayStruct *arrayP = procArray; TransactionId result; @@ -1340,14 +1341,7 @@ GetOldestXmin(Relation rel, bool ignoreVacuum) volatile PGPROC *proc = &allProcs[pgprocno]; volatile PGXACT *pgxact = &allPgXact[pgprocno]; - /* - * Backend is doing logical decoding which manages xmin separately, - * check below. - */ - if (pgxact->vacuumFlags & PROC_IN_LOGICAL_DECODING) - continue; - - if (ignoreVacuum && (pgxact->vacuumFlags & PROC_IN_VACUUM)) + if (pgxact->vacuumFlags & flags) continue; if (allDbs || diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 5f38fa6b4f..945dd1d592 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -39,7 +39,12 @@ struct XidCache TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]; }; -/* Flags for PGXACT->vacuumFlags */ +/* + * Flags for PGXACT->vacuumFlags + * + * Note: If you modify these flags, you need to modify PROCARRAY_XXX flags + * in src/include/storage/procarray.h. + */ #define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ #define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ #define PROC_IN_ANALYZE 0x04 /* currently running analyze */ diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 9d5a13eb3b..c8e1ae517c 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -20,6 +20,28 @@ #include "utils/snapshot.h" +/* + * These are to implement PROCARRAY_FLAGS_XXX + * + * Note: These flags are cloned from PROC_XXX flags in src/include/storage/proc.h + * to avoid forcing to include proc.h when including procarray.h. So if you modify + * PROC_XXX flags, you need to modify these flags. + */ +#define PROCARRAY_VACUUM_FLAG 0x02 /* currently running lazy vacuum */ +#define PROCARRAY_ANALYZE_FLAG 0x04 /* currently running analyze */ +#define PROCARRAY_LOGICAL_DECODING_FLAG 0x10 /* currently doing logical + * decoding outside xact */ + +/* Use the following flags as an input "flags" to GetOldestXmin function */ +/* Consider all backends except for logical decoding ones which manage xmin separately */ +#define PROCARRAY_FLAGS_DEFAULT PROCARRAY_LOGICAL_DECODING_FLAG +/* Ignore vacuum backends */ +#define PROCARRAY_FLAGS_VACUUM PROCARRAY_FLAGS_DEFAULT | PROCARRAY_VACUUM_FLAG +/* Ignore analyze backends */ +#define PROCARRAY_FLAGS_ANALYZE PROCARRAY_FLAGS_DEFAULT | PROCARRAY_ANALYZE_FLAG +/* Ignore both vacuum and analyze backends */ +#define PROCARRAY_FLAGS_VACUUM_ANALYZE PROCARRAY_FLAGS_DEFAULT | PROCARRAY_VACUUM_FLAG | PROCARRAY_ANALYZE_FLAG + extern Size ProcArrayShmemSize(void); extern void CreateSharedProcArray(void); extern void ProcArrayAdd(PGPROC *proc); @@ -53,7 +75,7 @@ extern RunningTransactions GetRunningTransactionData(void); extern bool TransactionIdIsInProgress(TransactionId xid); extern bool TransactionIdIsActive(TransactionId xid); -extern TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum); +extern TransactionId GetOldestXmin(Relation rel, int flags); extern TransactionId GetOldestActiveTransactionId(void); extern TransactionId GetOldestSafeDecodingTransactionId(void); -- 2.40.0