Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oFpsa-0000P5-DL for pgsql-hackers@arkaria.postgresql.org; Mon, 25 Jul 2022 04:39:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oFpsY-0006BK-Uz for pgsql-hackers@arkaria.postgresql.org; Mon, 25 Jul 2022 04:39:38 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oFpsY-0006BB-FY for pgsql-hackers@lists.postgresql.org; Mon, 25 Jul 2022 04:39:38 +0000 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1oFpsV-0007bF-J2 for pgsql-hackers@postgresql.org; Mon, 25 Jul 2022 04:39:37 +0000 Received: by mail-pj1-x1033.google.com with SMTP id t2-20020a17090a4e4200b001f21572f3a4so9173815pjl.0 for ; Sun, 24 Jul 2022 21:39:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=xGIFA+W7bdUMuEIIRoiSVwzLWv9ixPxZSDqyCIMQuUA=; b=EhDZYed3jHPJmk6H+2v7Yk6Yh4EdH0B9Ncu0F8s2lWpzy2QCKYEPpGIrqWYQXC60Pq hsf+dWXfJoCrTSgizL9Kg+v3EZaMaglPeJ5VvnaF1uXfta22SSIaUmjboqVruAIL7gmJ dgelqzzlbqvw8dpH4F/oTbDCTuin7zd/8IkBVahGCkWdeKkcaPM7ya82XTjTLdOLw6so IQxr+0ML9K4OJP5DdmgJBweMrh1YUgnSfMtU47YuT/VbODaJnmnZ8Gf62CEjzkiPxjuq 7hCXmlVHR3v3bAto95rwd3hfPm+CYF+qveSkQFT3X4jhFY3psOz3iitX1lXBC6pUPOF7 bVyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=xGIFA+W7bdUMuEIIRoiSVwzLWv9ixPxZSDqyCIMQuUA=; b=ntB9+KZ6B7NFNPVNitLZSHZOKOwAUwA0XUWlSzcMdY4JfF3ZdMOV/1bN6BEfyGKGxa cyxO2PbbklngEoFJwwALoz1ow7NC+lvhGL+Utl1tNmNIbF31ere+95E+eqPCTFxn9D19 OuAQgw8U/sKgc9oxZmV6Udlv0ay32aqVyEjD6s9lqrzXXhgz0GRcXQXZ+TvBdOpRZKxw hiLwyxXF0J3a3KGmpfcLswGLRjxDVW1eXaCZF+ZtHP9zd0W0FYwXzi9PI/xhVdYoiBjt PhwxnIyWzHCJZ4QQIlyJvSj9PsfxeZWkEvGUmJEc/lVOdQebtO8NBYUJU6pbPSTg/xvC ospA== X-Gm-Message-State: AJIora+nUR1zTO7AcTam1/L1eXIg9bb8PZ70K8Ngr9YWntjTX4BOjMTM nU8Qt6hpH/L9GzETRVmMznJWP+yjUFI= X-Google-Smtp-Source: AGRyM1v9ojuvAvi/e9N9CPcAgxl+PpEobZDFOtCIqbknvRxlftr+h/IYA8c7bz9DCPf4Rhk0VQ8OZg== X-Received: by 2002:a17:90a:c392:b0:1f2:5076:8901 with SMTP id h18-20020a17090ac39200b001f250768901mr12571027pjt.49.1658723974133; Sun, 24 Jul 2022 21:39:34 -0700 (PDT) Received: from nathanxps13 ([50.54.155.70]) by smtp.gmail.com with ESMTPSA id a24-20020aa79718000000b005255f5d8f9fsm8276849pfg.112.2022.07.24.21.39.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Jul 2022 21:39:33 -0700 (PDT) Date: Sun, 24 Jul 2022 21:39:31 -0700 From: Nathan Bossart To: pgsql-hackers@postgresql.org Subject: Re: predefined role(s) for VACUUM and ANALYZE Message-ID: <20220725043931.GA4087907@nathanxps13> References: <20220722203735.GB3996698@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline In-Reply-To: <20220722203735.GB3996698@nathanxps13> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jul 22, 2022 at 01:37:35PM -0700, Nathan Bossart wrote: > The attached patch adds a pg_vacuum_analyze role that allows VACUUM and > ANALYZE commands on all relations. I started by trying to introduce > separate pg_vacuum and pg_analyze roles, but that quickly became > complicated because the VACUUM and ANALYZE code is intertwined. To > initiate the discussion, here's the simplest thing I could think of. And here's the same patch, but with docs that actually build. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --ReaqsoxgOBHFXBhH Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="pg_vacuum_analyze_v2.patch" diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index b968f740cb..203b713a4e 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -148,11 +148,14 @@ ANALYZE [ VERBOSE ] [ table_and_columnsNotes - To analyze a table, one must ordinarily be the table's owner or a - superuser. However, database owners are allowed to + To analyze a table, one must ordinarily be the table's owner, a superuser, or + a role with privileges of the + pg_vacuum_analyze + role. However, database owners are allowed to analyze all tables in their databases, except shared catalogs. (The restriction for shared catalogs means that a true database-wide - ANALYZE can only be performed by a superuser.) + ANALYZE can only be performed by superusers and roles with + privileges of pg_vacuum_analyze.) ANALYZE will skip over any tables that the calling user does not have permission to analyze. diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index c582021d29..12d7b96fee 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -356,11 +356,14 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ pg_vacuum_analyze + role. However, database owners are allowed to vacuum all tables in their databases, except shared catalogs. (The restriction for shared catalogs means that a true database-wide - VACUUM can only be performed by a superuser.) + VACUUM can only be performed by superusers and roles with + privileges of pg_vacuum_analyze.) VACUUM will skip over any tables that the calling user does not have permission to vacuum. diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 6eaaaa36b8..6052bd0c4f 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -588,6 +588,13 @@ DROP ROLE doomed_role; the CHECKPOINT command. + + pg_vacuum_analyze + Allow executing the + VACUUM and + ANALYZE + commands on all tables. + diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 8df25f59d8..b3eb41a8cc 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -36,6 +36,7 @@ #include "access/xact.h" #include "catalog/namespace.h" #include "catalog/index.h" +#include "catalog/pg_authid.h" #include "catalog/pg_database.h" #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" @@ -574,7 +575,8 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options) * trying to vacuum or analyze the rest of the DB --- is this appropriate? */ if (pg_class_ownercheck(relid, GetUserId()) || - (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared)) + (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared) || + has_privs_of_role(GetUserId(), ROLE_PG_VACUUM_ANALYZE)) return true; relname = NameStr(reltuple->relname); @@ -583,11 +585,14 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options) { if (reltuple->relisshared) ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser can vacuum it", + (errmsg("skipping \"%s\" --- only superusers and roles with " + "privileges of pg_vacuum_analyze can vacuum it", relname))); else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE) ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it", + (errmsg("skipping \"%s\" --- only superusers, roles with " + "privileges of pg_vacuum_analyze, or the database " + "owner can vacuum it", relname))); else ereport(WARNING, @@ -606,11 +611,14 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options) { if (reltuple->relisshared) ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser can analyze it", + (errmsg("skipping \"%s\" --- only superusers and roles with " + "privileges of pg_vacuum_analyze can analyze it", relname))); else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE) ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it", + (errmsg("skipping \"%s\" --- only superusers, roles with " + "privileges of pg_vacuum_analyze, or the database " + "owner can analyze it", relname))); else ereport(WARNING, diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat index 3343a69ddb..f067fe1c57 100644 --- a/src/include/catalog/pg_authid.dat +++ b/src/include/catalog/pg_authid.dat @@ -84,5 +84,10 @@ rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', rolpassword => '_null_', rolvaliduntil => '_null_' }, +{ oid => '4549', oid_symbol => 'ROLE_PG_VACUUM_ANALYZE', + rolname => 'pg_vacuum_analyze', rolsuper => 'f', rolinherit => 't', + rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', + rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', + rolpassword => '_null_', rolvaliduntil => '_null_' }, ] diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index c63a157e5f..859be4c13e 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -302,18 +302,18 @@ VACUUM (ANALYZE) vacowned; WARNING: skipping "vacowned" --- only table or database owner can vacuum it -- Catalog VACUUM pg_catalog.pg_class; -WARNING: skipping "pg_class" --- only superuser or database owner can vacuum it +WARNING: skipping "pg_class" --- only superusers, roles with privileges of pg_vacuum_analyze, or the database owner can vacuum it ANALYZE pg_catalog.pg_class; -WARNING: skipping "pg_class" --- only superuser or database owner can analyze it +WARNING: skipping "pg_class" --- only superusers, roles with privileges of pg_vacuum_analyze, or the database owner can analyze it VACUUM (ANALYZE) pg_catalog.pg_class; -WARNING: skipping "pg_class" --- only superuser or database owner can vacuum it +WARNING: skipping "pg_class" --- only superusers, roles with privileges of pg_vacuum_analyze, or the database owner can vacuum it -- Shared catalog VACUUM pg_catalog.pg_authid; -WARNING: skipping "pg_authid" --- only superuser can vacuum it +WARNING: skipping "pg_authid" --- only superusers and roles with privileges of pg_vacuum_analyze can vacuum it ANALYZE pg_catalog.pg_authid; -WARNING: skipping "pg_authid" --- only superuser can analyze it +WARNING: skipping "pg_authid" --- only superusers and roles with privileges of pg_vacuum_analyze can analyze it VACUUM (ANALYZE) pg_catalog.pg_authid; -WARNING: skipping "pg_authid" --- only superuser can vacuum it +WARNING: skipping "pg_authid" --- only superusers and roles with privileges of pg_vacuum_analyze can vacuum it -- Partitioned table and its partitions, nothing owned by other user. -- Relations are not listed in a single command to test ownership -- independently. --ReaqsoxgOBHFXBhH--