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 1sM32D-000MF6-VS for pgsql-hackers@arkaria.postgresql.org; Tue, 25 Jun 2024 10:04:22 +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 1sM32C-00EmCR-76 for pgsql-hackers@arkaria.postgresql.org; Tue, 25 Jun 2024 10:04:20 +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.94.2) (envelope-from ) id 1sM32B-00EmCG-ST for pgsql-hackers@lists.postgresql.org; Tue, 25 Jun 2024 10:04:20 +0000 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sM328-003SZ4-Tl for pgsql-hackers@lists.postgresql.org; Tue, 25 Jun 2024 10:04:18 +0000 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-a7245453319so400209866b.1 for ; Tue, 25 Jun 2024 03:04:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1719309855; x=1719914655; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=kSwBTTVH2cACcP/fOH3idu+hw7iKhCPsW+AsSxrRz0U=; b=SoJ/GteNBTR7ZoBLIUpcdc0RM/KHZwl9LP5XQgCaxzmjL5xCMsB3nsOWqoMWAsI3ZW fYf6A6luvjr1eGcXm9vR7mQDYfVa9hRKvc8BPcWNIqUG7q75YVQUmbpq7VwsBszkZn1T dBYZce1RdlcQ+2vLkcmLHWrKDX4ZBiewyhYAEdW/qCpxD5jwNmHA4kDM2cOGqfgWRMoG i81eODG0wyeFiKZhwTFLw/BupNmEimriDFrBsJuKMNwWHcZTC11cYf12HLGXJItkBXOM jlHr+XyFcW4+/WHdLnl5PHvf/NrbIgEyQluQpQ/Akyh8yoIZTCynEUTEh+oEGA4bl/SZ JUFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719309855; x=1719914655; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kSwBTTVH2cACcP/fOH3idu+hw7iKhCPsW+AsSxrRz0U=; b=HfO5015elZFiGN2p0wmG3ORw842g9bed3FIfUeNBAUjfrn0+9pJju/fVhKOkdRDVGG 3jJmoa32d2BdVW1TAd3o2tWEunrQ4x08LYCCYtPHwS/MCI/+iXjAXw8J4/CzfW9mqS+B CBWC92wX0ss71wKMj3P/MNMhdz0zjLYgaHKlAqxPMu9t43Qe3zXVqPo3kki4mGUdpQr+ H0HqfI9h+fBYGfqyg5W4JgZPWdIUeCrI96giwrWCavNS4HBJP3d2E6t22o7XgU4zYzqO EVLKRUbh1uqV/BDVHGCtGWb2rSUXRAgB5DB61NVTbYiiCmCslVMNW4DL07X5iL11J+4e ybSQ== X-Gm-Message-State: AOJu0YxobOMGblEEvrKc786gS1OeAHdNoSz8b4J9S1Rm7IeAKLzFMPIV FJXFbZz5656eHOUEwKFqNG1uIl3fMsO2b2Sm2xQvDLf0A+0g2zxPOLovu9RzsA== X-Google-Smtp-Source: AGHT+IGNlM4MajzruasF5+SQXf06fTBHqbSX6PMJMJXUvicgd3z23UbejuU9DcTSs1hhrhJtG9Jllw== X-Received: by 2002:a17:906:3c4c:b0:a6f:a2aa:a4c7 with SMTP id a640c23a62f3a-a6ffe2706b2mr646287666b.3.1719309855212; Tue, 25 Jun 2024 03:04:15 -0700 (PDT) Received: from [10.137.0.18] (srv1.mobissw.com. [89.235.0.226]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a725c54f238sm149116566b.14.2024.06.25.03.04.14 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 25 Jun 2024 03:04:14 -0700 (PDT) Message-ID: <9266c8df-0df7-4605-ba5a-b204c5e52586@enterprisedb.com> Date: Tue, 25 Jun 2024 12:04:14 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: scalability bottlenecks with (many) partitions (and more) To: Robert Haas Cc: PostgreSQL Hackers References: <510b887e-c0ce-4a0c-a17a-2c6abb8d9a5c@enterprisedb.com> Content-Language: en-US From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 6/24/24 17:05, Robert Haas wrote: > On Sun, Jan 28, 2024 at 4:57 PM Tomas Vondra > wrote: >> For NUM_LOCK_PARTITIONS this is pretty simple (see 0001 patch). The >> LWLock table has 16 partitions by default - it's quite possible that on >> machine with many cores and/or many partitions, we can easily hit this. >> So I bumped this 4x to 64 partitions. > > I think this probably makes sense. I'm a little worried that we're > just kicking the can down the road here where maybe we should be > solving the problem in some more fundamental way, and I'm also a > little worried that we might be reducing single-core performance. But > it's probably fine. > Yeah, I haven't seen this causing any regressions - the sensitive paths typically lock only one partition, so having more of them does not affect that. Or if it does, it's likely a reasonable trade off as it reduces the risk of lock contention. That being said, I don't recall benchmarking this patch in isolation, only with the other patches. Maybe I should do that ... >> What I ended up doing is having a hash table of 16-element arrays. There >> are 64 "pieces", each essentially the (16 x OID + UINT64 bitmap) that we >> have now. Each OID is mapped to exactly one of these parts as if in a >> hash table, and in each of those 16-element parts we do exactly the same >> thing we do now (linear search, removal, etc.). This works great, the >> locality is great, etc. The one disadvantage is this makes PGPROC >> larger, but I did a lot of benchmarks and I haven't seen any regression >> that I could attribute to this. (More about this later.) > > I think this is a reasonable approach. Some comments: > > - FastPathLocalUseInitialized seems unnecessary to me; the contents of > an uninitialized local variable are undefined, but an uninitialized > global variable always starts out zeroed. > OK. I didn't realize global variables start a zero. > - You need comments in various places, including here, where someone > is certain to have questions about the algorithm and choice of > constants: > > +#define FAST_PATH_LOCK_REL_GROUP(rel) (((uint64) (rel) * 7883 + 4481) > % FP_LOCK_GROUPS_PER_BACKEND) > Yeah, definitely needs comment explaining this. I admit those numbers are pretty arbitrary primes, to implement a trivial hash function. That was good enough for a PoC patch, but maybe for a "proper" version this should use a better hash function. It needs to be fast, and maybe it doesn't matter that much if it's not perfect. > When I originally coded up the fast-path locking stuff, I supposed > that we couldn't make the number of slots too big because the > algorithm requires a linear search of the whole array. But with this > one trick (a partially-associative cache), there's no real reason that > I can think of why you can't make the number of slots almost > arbitrarily large. At some point you're going to use too much memory, > and probably before that point you're going to make the cache big > enough that it doesn't fit in the CPU cache of an individual core, at > which point possibly it will stop working as well. But honestly ... I > don't quite see why this approach couldn't be scaled quite far. > I don't think I've heard the term "partially-associative cache" before, but now that I look at the approach again, it very much reminds me how set-associative caches work (e.g. with cachelines in CPU caches). It's a 16-way associative cache, assigning each entry into one of 16 slots. I must have been reading some papers in this area shortly before the PoC patch, and the idea came from there, probably. Which is good, because it means it's a well-understood and widely-used approach. > Like, if we raised FP_LOCK_GROUPS_PER_BACKEND from your proposed value > of 64 to say 65536, would that still perform well? I'm not saying we > should do that, because that's probably a silly amount of memory to > use for this, but the point is that when you start to have enough > partitions that you run out of lock slots, performance is going to > degrade, so you can imagine wanting to try to have enough lock groups > to make that unlikely. Which leads me to wonder if there's any > particular number of lock groups that is clearly "too many" or whether > it's just about how much memory we want to use. > That's an excellent question. I don't know. I agree 64 groups is pretty arbitrary, and having 1024 may not be enough even with a modest number of partitions. When I was thinking about using a higher value, my main concern was that it'd made the PGPROC entry larger. Each "fast-path" group is ~72B, so 64 groups is ~4.5kB, and that felt like quite a bit. But maybe it's fine and we could make it much larger - L3 caches tend to be many MBs these days, although AFAIK it's shared by threads running on the CPU. I'll see if I can do some more testing of this, and see if there's a value where it stops improving / starts degrading, etc. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company