From 08f91f3d7554bc482d615230ad29ae096a8029d7 Mon Sep 17 00:00:00 2001 From: ChangAo Chen Date: Sat, 27 Jun 2026 15:44:53 +0800 Subject: [PATCH v7] Do not check permissions in get_all_vacuum_rels. When doing a database-wide vacuum, we scan pg_class to build a list of vacuumable relations without locking them. The permissions check might report an error if a concurrent drop happens because of failing to search the syscache. This commit remove the permissions check in get_all_vacuum_rels and the permissions check will happen later when we process each relation. This also makes the behavior consistent across database-wide vacuum, vacuum and autovacuum. --- src/backend/commands/analyze.c | 7 ++----- src/backend/commands/vacuum.c | 12 +++--------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..f303c3eed7d 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -149,11 +149,8 @@ analyze_rel(Oid relid, RangeVar *relation, return; /* - * Check if relation needs to be skipped based on privileges. This check - * happens also when building the relation list to analyze for a manual - * operation, and needs to be done additionally here as ANALYZE could - * happen across multiple transactions where privileges could have changed - * in-between. Make sure to generate only logs for ANALYZE in this case. + * Check if relation needs to be skipped based on privileges. Make sure + * to generate only logs for ANALYZE in this case. */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..59d7640a6db 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -723,6 +723,7 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, char *relname; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); + Assert(CheckRelationOidLockedByMe(relid, AccessShareLock, true)); /*---------- * A role has privileges to vacuum or analyze the relation if any of the @@ -1068,10 +1069,6 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) !isTempOrTempToastNamespace(classForm->relnamespace)) continue; - /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) - continue; - /* * Build VacuumRelation(s) specifying the table OIDs to be processed. * We omit a RangeVar since it wouldn't be appropriate to complain @@ -2107,11 +2104,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, priv_relid = RelationGetRelid(rel); /* - * Check if relation needs to be skipped based on privileges. This check - * happens also when building the relation list to vacuum for a manual - * operation, and needs to be done additionally here as VACUUM could - * happen across multiple transactions where privileges could have changed - * in-between. Make sure to only generate logs for VACUUM in this case. + * Check if relation needs to be skipped based on privileges. Make sure + * to only generate logs for VACUUM in this case. */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, -- 2.54.0