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.94.2) (envelope-from ) id 1rnU5g-00DWJ8-GK for pgsql-hackers@arkaria.postgresql.org; Fri, 22 Mar 2024 01:53:04 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rnU5d-0003hw-Dy for pgsql-hackers@arkaria.postgresql.org; Fri, 22 Mar 2024 01:53:01 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rnU5d-0003ho-2Q for pgsql-hackers@lists.postgresql.org; Fri, 22 Mar 2024 01:53:01 +0000 Received: from mail-il1-x136.google.com ([2607:f8b0:4864:20::136]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rnU5V-005lnB-9H for pgsql-hackers@lists.postgresql.org; Fri, 22 Mar 2024 01:53:00 +0000 Received: by mail-il1-x136.google.com with SMTP id e9e14a558f8ab-368480eb81bso7367715ab.0 for ; Thu, 21 Mar 2024 18:52:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711072373; x=1711677173; 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=3kIvlmDd05PiOgmHVZ2kRta8a+XP4CMF+WsajfgjazU=; b=QfBgDidnpFznWw6vR/wsfqBaVtyZkYjzVwLBfcv/vadyIiZihy7M9R1HQOaN86yycE S4YS4OLpscmk4MuXGDmqFcW7Uj5EyklX8aiHZhodyeILHGi0kNI3mHd42qBZvlM3wyuV RbZjhl5ea/+6eSt4pJ4t6rOlX1o1CyaGV6EFoQID/zqwSbH/BwQXlZ1ZL2Mt6xSJJOLc JETRwMrMXigyrgxIKkx8cD4y3Z+y0JjEAlUlKqsVrG69Ddixbzy5EyiGtZ+wgSGtG6C+ ICuIt7faPy65TWupQpngnXDYJILN1giCUOdO9PQDhlm4EkiEMZmvbfFmBp+u7q0AD9W6 ZrEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711072373; x=1711677173; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=3kIvlmDd05PiOgmHVZ2kRta8a+XP4CMF+WsajfgjazU=; b=uwqFktCXGK7JqHMY6rtLBKsjCIm1Ug1peaHQNUVN4W90CCRmgBnjFVGa667WZnICFu p8sS5n0nzxN5eziE/CtCCQMnTGfOnlUQ1PNnHalKMUmRyUnCGSeSdxTocclgWRIBxB+/ +tSHWCWunMAIEIWKEtw78bKUclGbWoR1iX9PFuC+bcU73+M1S5Xp7U872eelZfN3Fe9S Jx/lY6zQKWUOHN0r1UbyqrpXxzaE2aLEz5AQvN2Egrma4S4ijYU6qd7JHyUbpEZdcqhZ eSIyLawC56qV8MRQKLlw/e5HXih0m3Uxk8jRVwz0PYaOEaOSfpw96TmXAQcT6GPSD+KC 7ACA== X-Gm-Message-State: AOJu0Yzy/mLpmo4DK/ShVVdHU4Pv1gfBi8mda2DSGO0ZPoTcA4sgi62N tf7VgWgbLHif/e/l8647VBKDXjoLWMwGD3TZx6Cku1y1B47x24Ec X-Google-Smtp-Source: AGHT+IH82N6Zn2aE+z5EqVXhBMQDDNdQMs5hwjrayjTr88rK9lkC3ikDD90v2x52FvcwhK6qBSkWuQ== X-Received: by 2002:a05:6e02:11b1:b0:366:adfe:7a19 with SMTP id 17-20020a056e0211b100b00366adfe7a19mr1242127ilj.1.1711072373515; Thu, 21 Mar 2024 18:52:53 -0700 (PDT) Received: from nathanxps13 (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id w34-20020a05663837a200b004773a779d24sm243955jal.36.2024.03.21.18.52.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 18:52:53 -0700 (PDT) Date: Thu, 21 Mar 2024 20:52:51 -0500 From: Nathan Bossart To: Tom Lane Cc: pgsql-hackers@lists.postgresql.org, alex work , Robert Haas Subject: Re: Slow GRANT ROLE on PostgreSQL 16 with thousands of ROLEs Message-ID: <20240322015251.GA2193900@nathanxps13> References: <341186.1711037256@sss.pgh.pa.us> <619340.1711050134@sss.pgh.pa.us> <642442.1711053105@sss.pgh.pa.us> <20240321204012.GA1992418@nathanxps13> <20240322005139.GA2060816@nathanxps13> <806361.1711069194@sss.pgh.pa.us> <20240322010332.GA2109205@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="u3/rZRmxL6MmkK24" Content-Disposition: inline In-Reply-To: <20240322010332.GA2109205@nathanxps13> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --u3/rZRmxL6MmkK24 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Mar 21, 2024 at 08:03:32PM -0500, Nathan Bossart wrote: > On Thu, Mar 21, 2024 at 08:59:54PM -0400, Tom Lane wrote: >> However ... I just remembered that we have a Bloom filter implementation >> in core now (src/backend/lib/bloomfilter.c). How about using that >> to quickly reject (hopefully) most role OIDs, and only do the >> list_member_oid check if the filter passes? > > Seems worth a try. I've been looking for an excuse to use that... The Bloom filter appears to help a bit, although it regresses the create-roles.sql portion of the test. I'm assuming that's thanks to all the extra pallocs and pfrees, which are probably avoidable if we store the filter in a long-lived context and just clear it at the beginning of each call to roles_is_member_of(). HEAD hash hash+bloom create 2.02 2.06 2.92 grant 4.63 0.27 0.08 -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --u3/rZRmxL6MmkK24 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="bloom.patch" diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index cf5d08576a..445a14646c 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -36,6 +36,7 @@ #include "common/hashfn.h" #include "foreign/foreign.h" #include "funcapi.h" +#include "lib/bloomfilter.h" #include "lib/qunique.h" #include "miscadmin.h" #include "utils/acl.h" @@ -4946,6 +4947,7 @@ roles_is_member_of(Oid roleid, enum RoleRecurseType type, ListCell *l; List *new_cached_roles; MemoryContext oldctx; + bloom_filter *bf; Assert(OidIsValid(admin_of) == PointerIsValid(admin_role)); if (admin_role != NULL) @@ -4987,6 +4989,9 @@ roles_is_member_of(Oid roleid, enum RoleRecurseType type, */ roles_list = list_make1_oid(roleid); + bf = bloom_create(1024, work_mem, 0); + bloom_add_element(bf, (unsigned char *) &roleid, sizeof(Oid)); + foreach(l, roles_list) { Oid memberid = lfirst_oid(l); @@ -5023,16 +5028,29 @@ roles_is_member_of(Oid roleid, enum RoleRecurseType type, * graph, we must test for having already seen this role. It is * legal for instance to have both A->B and A->C->B. */ - roles_list = list_append_unique_oid(roles_list, otherid); + if (bloom_lacks_element(bf, (unsigned char *) &otherid, sizeof(Oid))) + roles_list = lappend_oid(roles_list, otherid); + else + roles_list = list_append_unique_oid(roles_list, otherid); + bloom_add_element(bf, (unsigned char *) &otherid, sizeof(Oid)); } ReleaseSysCacheList(memlist); /* implement pg_database_owner implicit membership */ if (memberid == dba && OidIsValid(dba)) - roles_list = list_append_unique_oid(roles_list, - ROLE_PG_DATABASE_OWNER); + { + Oid dbowner = ROLE_PG_DATABASE_OWNER; + + if (bloom_lacks_element(bf, (unsigned char *) &dbowner, sizeof(Oid))) + roles_list = lappend_oid(roles_list, ROLE_PG_DATABASE_OWNER); + else + roles_list = list_append_unique_oid(roles_list, ROLE_PG_DATABASE_OWNER); + bloom_add_element(bf, (unsigned char *) &dbowner, sizeof(Oid)); + } } + bloom_free(bf); + /* * Copy the completed list into TopMemoryContext so it will persist. */ --u3/rZRmxL6MmkK24--