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 1rngBR-00EUf1-7a for pgsql-hackers@arkaria.postgresql.org; Fri, 22 Mar 2024 14:47:49 +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 1rngBP-004KHk-Oq for pgsql-hackers@arkaria.postgresql.org; Fri, 22 Mar 2024 14:47:48 +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 1rngBP-004KHY-Fp for pgsql-hackers@lists.postgresql.org; Fri, 22 Mar 2024 14:47:47 +0000 Received: from mail-il1-x135.google.com ([2607:f8b0:4864:20::135]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rngBJ-005rds-4y for pgsql-hackers@lists.postgresql.org; Fri, 22 Mar 2024 14:47:46 +0000 Received: by mail-il1-x135.google.com with SMTP id e9e14a558f8ab-366a4bcb2a8so9845125ab.3 for ; Fri, 22 Mar 2024 07:47:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711118861; x=1711723661; 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=vdrPYb7DD4Fp9Q8i+9Nb9WKahvpv8UcuwZUzH0dU1sA=; b=gS2jUGN6PG2LcvCQSFt3TfTPj6m9je3+BQtd0FwOsP8KJKku+9jQo38evyOgjux12V +pvAoZw+FzLXAjMPnzkBovFjA938IzG3wn5dbOMiHK6uTpanUU58U9yX/QDRMp01HYkh ek4zmwybbdlaTbfZnrIzJefsQCoJxFnmXtcDZifJi9zPJ+9ZGvTvCWWBsQNFpyjeQzlQ WBIJ51cjMagBlMHe+3PlUG9V5CqdkDFpJ6xtSMUx8lAZooSaxl8B+bIOUoXTZCpnnfaM vOQ+dgHNR3jrW+O5QtxeTp2AwIm/V/Fi4qOi5V8B+aDFHVk+s1FToMYtbjjJkfcjF7GA G/Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711118861; x=1711723661; 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=vdrPYb7DD4Fp9Q8i+9Nb9WKahvpv8UcuwZUzH0dU1sA=; b=fDCq/sVXhHfJnG7GQ7uH2lqVBf6P5BKAMYcBKw3wTmZbmzi6aa1Sku9EV8Y1oiIkWY 54DHPJWH70aL+pS7mHCySBnH5EgXOQYywmkSGwotkVwaRnGf0n6B1+LYW63GuG4yJOZX Y3Ssk1Oq2pllNE9ypFEdmL7gPSszzavImG34VU2PKebQKnhhuNj+CpNU9FV5xfrNC6k8 FZ8Ybzm+0IFHKdY+yryogXodnrqmq3pNSfqYQg7gMuR+2ttyMKMpHVLpk6cHUuhyc/wF FB7TujLQ2/zgX1YsibcfrvXTjNvhpU7dkEsofzbU8Ej/RKpX2ccZSWT3rEE7QcjxMlpK 7Zow== X-Gm-Message-State: AOJu0YzJ845COms/2tsmXbd+Q/L0xnUwVjGAUkWFRJV7vKLEX+NvYPUp tDydcINEXzBnenTpHZhR7dfXr+1h2ixFwfpFiihJoa/J6WJ2Zohi X-Google-Smtp-Source: AGHT+IEohKd0y4vOazyHY2UI1y3tnI60ViA425HMfIDgZrcM/n8Xj5d5dnBnYqs7RSLw5od//d6enQ== X-Received: by 2002:a92:c8c1:0:b0:368:7571:6840 with SMTP id c1-20020a92c8c1000000b0036875716840mr1257111ilq.22.1711118861583; Fri, 22 Mar 2024 07:47:41 -0700 (PDT) Received: from nathanxps13 (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id g24-20020a0566380bd800b004772993bc0esm570406jad.142.2024.03.22.07.47.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Mar 2024 07:47:41 -0700 (PDT) Date: Fri, 22 Mar 2024 09:47:39 -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: <20240322144739.GA2321246@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> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="liOOAslEiF7prFVr" Content-Disposition: inline In-Reply-To: <806361.1711069194@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --liOOAslEiF7prFVr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Mar 21, 2024 at 08:59:54PM -0400, Tom Lane wrote: > Nathan Bossart writes: >> On Thu, Mar 21, 2024 at 03:40:12PM -0500, Nathan Bossart wrote: >>> On Thu, Mar 21, 2024 at 04:31:45PM -0400, Tom Lane wrote: >>>> I don't think we have any really cheap way to de-duplicate the role >>>> OIDs, especially seeing that it has to be done on-the-fly within the >>>> collection loop, and the order of roles_list is at least potentially >>>> interesting. Not sure how to make further progress without a lot of >>>> work. > >>> Assuming these are larger lists, this might benefit from optimizations >>> involving SIMD intrinsics. > >> Never mind. With the reproduction script, I'm only seeing a ~2% >> improvement with my patches. > > Yeah, you cannot beat an O(N^2) problem by throwing SIMD at it. I apparently had some sort of major brain fade when I did this because I didn't apply your hashing patch when I ran this SIMD test. With it applied, I see a speedup of ~39%, which makes a whole lot more sense to me. If I add the Bloom patch (updated with your suggestions), I get another ~73% improvement from there, and a much smaller regression in the role creation portion. hash hash+simd hash+simd+bloom create 1.27 1.27 1.28 grant 0.18 0.11 0.03 -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --liOOAslEiF7prFVr Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="bloom_v2.patch" diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index cf5d08576a..4952dc9c1e 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 = NULL; Assert(OidIsValid(admin_of) == PointerIsValid(admin_role)); if (admin_role != NULL) @@ -5023,16 +5025,46 @@ 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 ((bf && bloom_lacks_element(bf, (unsigned char *) &otherid, sizeof(Oid))) || + !list_member_oid(roles_list, otherid)) + { + if (bf == NULL && list_length(roles_list) > 1000) + { + bf = bloom_create(1024 * 1024, work_mem, 0); + foreach_oid(role, roles_list) + bloom_add_element(bf, (unsigned char *) &role, sizeof(Oid)); + } + roles_list = lappend_oid(roles_list, otherid); + if (bf) + 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 ((bf && bloom_lacks_element(bf, (unsigned char *) &dbowner, sizeof(Oid))) || + !list_member_oid(roles_list, dbowner)) + { + if (bf == NULL && list_length(roles_list) > 1000) + { + bf = bloom_create(1024 * 1024, work_mem, 0); + foreach_oid(role, roles_list) + bloom_add_element(bf, (unsigned char *) &role, sizeof(Oid)); + } + roles_list = lappend_oid(roles_list, dbowner); + if (bf) + bloom_add_element(bf, (unsigned char *) &dbowner, sizeof(Oid)); + } + } } + if (bf) + bloom_free(bf); + /* * Copy the completed list into TopMemoryContext so it will persist. */ --liOOAslEiF7prFVr--