agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v9a 04/22] ci: Store build/meson-logs and name "id: os" task 253+ messages / 2 participants [nested] [flat]
* [PATCH v9a 04/22] ci: Store build/meson-logs and name "id: os" task @ 2026-06-03 05:31 Andres Freund <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Andres Freund @ 2026-06-03 05:31 UTC (permalink / raw) --- .github/workflows/pg-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml index 8594d540f6a..a4fd4f42a50 100644 --- a/.github/workflows/pg-ci.yml +++ b/.github/workflows/pg-ci.yml @@ -157,7 +157,8 @@ jobs: ulimit -a -H && ulimit -a -S env - - id: os + - name: Parse ci-os-only + id: os env: MSG: ${{ github.event.head_commit.message }} shell: bash @@ -328,6 +329,7 @@ jobs: **/*.diffs **/regress_log_* **/crashlog-*.txt + build/meson-logs/** if-no-files-found: ignore -- 2.54.0.380.gc69baaf57b --lyfxwjjve3vodszg Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v9a-0005-ci-Use-mingw-pkgconf-instead-of-pkg-config-packa.patch" ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 253+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 253+ messages in thread
end of thread, other threads:[~2026-06-30 15:29 UTC | newest] Thread overview: 253+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2026-06-03 05:31 [PATCH v9a 04/22] ci: Store build/meson-logs and name "id: os" task Andres Freund <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox