Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1weaQ0-004sym-0E for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jun 2026 15:30:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1weaPy-008v9z-26 for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jun 2026 15:30:34 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1weaPy-008v9r-13 for pgsql-hackers@lists.postgresql.org; Tue, 30 Jun 2026 15:30:34 +0000 Received: from mail-oa1-x30.google.com ([2001:4860:4864:20::30]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1weaPv-000000012Cj-4Bq5 for pgsql-hackers@lists.postgresql.org; Tue, 30 Jun 2026 15:30:33 +0000 Received: by mail-oa1-x30.google.com with SMTP id 586e51a60fabf-44755d837e8so3114187fac.3 for ; Tue, 30 Jun 2026 08:30:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782833429; x=1783438229; darn=lists.postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=wWpJVCFyQz1CS6Tx+4FSko7+wBjqOyubsi9eYWNitTE=; b=OL3mgsifFSKq7/DmLr+RV0HZ+awDQH9e2WafszzbLUmzAc5Rl8INmYPhMJpttoyeVR XaxdByVChGVhhWacxkNXETcdwLVOVs5Nym++6dRBDHD2nK71IVgJUvIRy6MtMf0Ca+IC jyjiHwkgsgTNAoU27o62ZyFJlRZnhicApQtamua6u8b20wCWwVVptBKXdrg5yk/kt+xw nDEJRayfVXRRrbxOemXpSBelhRxUffDfVvEEUpeUYlqRaVE84hMJM/w5OW1fOpj/zeKi fWyF5nFUm7iGIh2E13u+PGF43aqD5BYTYGbweRlQLveSp4kGfsd1unCD1xPk+HzkQfxo W1Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782833429; x=1783438229; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wWpJVCFyQz1CS6Tx+4FSko7+wBjqOyubsi9eYWNitTE=; b=cTnicVUPfO1EnRiZXhUsayyGBj6qNDv/ezrtlVU6Kg4uXAGes/gWDywdl730+Q06Lf hN7sT42ZgI5LgeYgo83OQoAuJe1ecZ6yDDYWejBTnwGhcBPA6RCcCckFeTxaEyazM8TD 1W/G94neDLG+cx+rpf3aD400fC8SBnubSWVTbUc4bCn4SkSPr8C95OKlXbxwv53+22cz LIH8bFByNtAVbfkLV940C7N/OlYMFmxwtaca9LsqUTdQmMjRj1PfOuUrbv4RKCXML+eJ BzbCxVOHSg8C+WFSp4ztdI4jQbWytTVAIQx6tU2nYT6cOlm8LWFiyL77FjlPVwUj4Qd7 Dy0g== X-Forwarded-Encrypted: i=1; AHgh+RrefQjpErARcBkOmdLj9/bSfz9UifUsB3F0J/VPsNzpxxzR8CgDtZv2ruLAuF2EI3StUFuAgeSMuGvqVj6w@lists.postgresql.org X-Gm-Message-State: AOJu0YxvQyeJ4BdAcTpCPfJT7cT/5LOvX2/Ym97sxdSuaPPam7pj87PY h8/EQlELivaGbThPMgZo3aWbNLVvp5ijazZNXr2uWv2dPn7FeL2lpHrl X-Gm-Gg: AfdE7ckzXTgOW0dELsHkdmMEzbcrczZ8tX0WGsdL+Lv4vQvcEKJes83hN6B2p+/NWQN W6LqrrgD+84SVHqlEfxzhY3ExOADdCz+yppF7pf3WrUEkpEkxUvEdfRIBfkiCzkSgwUXwFAvJC2 KQMTgyvKoR1/fTYYvVdUUHXGw66UoKhNQV2N/LUEFir5YjYExES9L8weMRtLJHAWlpDHw2Y7Pw+ nwkkji9eniVGEBu+ktTTShcfREx5tIWboadhfIqLyVyNBBiXiK+P7siID/6a5RnT7Qw0cRR9Ae2 tug9NCnlCeksbvsS+8d09NnFe2xJs0A8j0ICnWvKQoOzeIjDkN/JqQYuhu2N1gmGL4DcN6bzwoM 6J/DSKyNYdwJUltplJsx/FbfVt0Vyo/um/zEiXx32P9mng5F7TEY8SObZZgODL6voltFksvnhem J2C1GZvHaMo7RYORQzgm9KHJD+9/P3vRUpi4nnUNHtZA1XRBk4TJ+2q3zkStSuPiWtM4kmF4/gV KrAQ7LRIls= X-Received: by 2002:a05:6870:955b:b0:44a:6cd8:9935 with SMTP id 586e51a60fabf-44a6cd89d5cmr1292375fac.1.1782833429386; Tue, 30 Jun 2026 08:30:29 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-448dc1019f5sm2570257fac.17.2026.06.30.08.30.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 08:30:27 -0700 (PDT) Date: Tue, 30 Jun 2026 10:30:25 -0500 From: Nathan Bossart To: Michael Paquier Cc: Bharath Rupireddy , cca5507 , Kyotaro Horiguchi , pgsql-hackers , Jeff Davis Subject: Re: Handle concurrent drop when doing whole database vacuum Message-ID: References: <20260615.145410.2255263073807327959.horikyota.ntt@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="dDwC+h/KQNl/aRwi" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --dDwC+h/KQNl/aRwi Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Jun 30, 2026 at 01:47:41PM +0900, Michael Paquier wrote: > Something that still feels off to me is to blindly use _ext() in > vacuum_is_permitted_for_relation(), where we *may* already hold a lock > on the relation whose ACL is checked. In this case missing a relation > is not fine, so this would make the code more brittle in the > single-relation case under autovacuum or a VACUUM with a list of > relations provided by a user. Yeah, so we should only use it for get_all_vacuum_rels(), as in the attached. -- nathan --dDwC+h/KQNl/aRwi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v8-0001-handle-concurrent-drop-in-database-wide-vacuum.patch From aad9a02072544a7bc2c3f861987748b815fcddc9 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 30 Jun 2026 10:29:16 -0500 Subject: [PATCH v8 1/1] handle concurrent drop in database-wide vacuum --- 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--