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 1vd8oC-00ESO2-09 for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jan 2026 15:17:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vd8oA-008b3v-1x for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jan 2026 15:17:19 +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.96) (envelope-from ) id 1vd8oA-008b3m-0y for pgsql-hackers@lists.postgresql.org; Tue, 06 Jan 2026 15:17:19 +0000 Received: from lahtoruutu.iki.fi ([2a0b:5c81:1c1::37]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vd8o8-004YDi-3D for pgsql-hackers@lists.postgresql.org; Tue, 06 Jan 2026 15:17:18 +0000 Received: from [10.0.2.15] (unknown [130.41.208.2]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: hlinnaka) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4dlvsk2gvqz49PwN; Tue, 06 Jan 2026 17:17:14 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1767712634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+3f8UevgCwmWr8lRtaNisKQkfUYu5qw+OVzdGzb6lYQ=; b=mZ6yIWJDkH/xK2GHTMuE0Kyn08UMuPsfNelWnjfCoIAmzj2tf4PSrQLKJIxubo62dwZJyj 2oEeygHYaHmW13M/vXjJ3+S5xN7Ye13le0Q7LAmJha2dNITePfz00JaKwsEKuWJJNBdekR 5LssA2lZ58gKke3lhaIwfIrM5ZCgCsnmKB8gGNxyuRobgFjn7d4AG6SpwEkWyWFeJCHwu7 RrpxuqpXWaUH50hVWOYodGVm0E7ia/B/u11Jy2EB4FQW37fYJH5svtTRcV+udket3uFUKJ an1Q4ilWeySBF/U9EBM/P1NNx25AI02Q+w0SWwAzW/eQ6hsh8Faa0fYgcZNWKQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1767712634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+3f8UevgCwmWr8lRtaNisKQkfUYu5qw+OVzdGzb6lYQ=; b=rOmau8yKFBWReY+8pez2VsRAqu7nUHpO43VYG4TQ/B420OJdE+OiMApWfRVIY0z2RrcimW WZIIHqpwOAuq1vNRJTPUT0TF0pRIBYevZuVORWo40bpKCxMuoYNz4PEuMxuscZbxCF/wW7 kmPBKg8mYI42bdxkA8NtGaOqsvuIcIIBpw6zJuRLK0jA1fqlKnwNyGLXD/0RMzkR2Ey02V 0cs6TFZq7bPR1COo2tZ9gdrmtUqleOChTrq3EqFapQfV8fQcvu0VwlKX61n+c+BJLQXQ73 Yd4udFnjdSlaZewTFWoY7sMhX5ztLt8jZm5OfxOEt41iF1deys+1Gfm6BHlP6Q== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=hlinnaka smtp.mailfrom=hlinnaka@iki.fi ARC-Seal: i=1; a=rsa-sha256; d=iki.fi; s=lahtoruutu; cv=none; t=1767712634; b=Tr8lF6KmoYYiIJlVi6SlD0WsX92CHFL8yl/I1dRFdAFawltqhu7/rIkZHwOCpTbBPPVY+e 0EKqqftgBbIZN9WENx5KEzjPWydWw+NCriAyYaRQEIDO0w4o31ESBTOVo+qG97Dq+jGC9J cooimk7iT7KApUzImLgVSBK9S6zvl0ZgilvHIz29g+DDbxuYLxwY+rTw96kiAKV1x3M9K6 USJXtLpX1HFkhzh6BQfoi0Q+tVQdPSTPlvFSRPzxwDkyThP8Lggf6mbJFPyFzu4WiJqn0t 9NpvdsEYOHDOkIcTlc3eHvrRCtu1usih7cMGFuXIzZBm4ERfvFy3hfKGLJcyRA== Message-ID: <818772a0-bb59-4107-8f1d-749e8b498b9a@iki.fi> Date: Tue, 6 Jan 2026 17:17:13 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Refactor PROCLOCK hash table into partitioned list allocator To: Matthias van de Meent Cc: Andrey Borodin , PostgreSQL Hackers References: <271502B5-C950-4428-AF69-9C6D62EF5F14@yandex-team.ru> <3d7e7d38-b3c1-4adf-8cb0-309dba08dba9@iki.fi> Content-Language: en-US From: Heikki Linnakangas In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 06/01/2026 16:58, Matthias van de Meent wrote: > On Tue, 6 Jan 2026 at 15:24, Heikki Linnakangas wrote: >> >> On 30/12/2025 14:37, Andrey Borodin wrote: >>> Hi hackers, >>> >>> Following up on the Discord discussion about the PROCLOCK hash table being >>> a "weird allocator" that we never actually use for lookups - I took a stab at >>> replacing it with a simpler partitioned free list approach as was suggested. >>> I was doing this mostly to educate myself on Lock Manager internals. >>> >>> The current implementation uses LockMethodProcLockHash purely as an allocator. >>> We never do hash lookups by key; we only allocate entries, link them to the lock's >>> procLocks list, and free them later. Using a full hash table for this adds >>> unnecessary complexity and maybe even overhead (I did not measure this). >>> >>> The attached patch replaces this with: >>> - ProcLockArray: A fixed-size array of all PROCLOCK structs (allocated at startup) >>> - ProcLockFreeList: Partitioned free lists, one per lock partition to reduce contention >>> - ProcLockAlloc/Free: Simple push/pop operations on the free lists >>> - PROCLOCK lookup: Linear traversal of lock->procLocks (see LockRefindAndRelease() >>> and FastPathGetRelationLockEntry()) >>> >>> The last point bothers me most. It seems like this traversals are expected to be short. >>> But I'm not 100% sure. >> >> Hmm, yeah the last point contradicts the premise that the hash table is >> used purely as an allocator. It *is* used for lookups, and you're >> replacing them with linear scans. That doesn't seem like an improvement. > > There are 2 types of PROCLOCK lookup used in LockRefindAndRelease and > FastPathGetRelationLockEntry: > - An active backend's PROCLOCK entries (in both LRAR and FPGRLE). > - Prepared transaction's PROCLOCK entries (only in LRAR, called from > lock_twophase_postcommit). There are also lookups in SetupLockInTable and in LockRelease. > For the backend's PROCLOCK entry lookup, we can use a backend-local > hash table, which only keeps track of where this backend's entries > are. Hmm, good point. In fact we already have that: there's a pointer to the current process's PROCLOCK entry in LOCALLOCK already. Can we use that to avoid the linear scans? There's this LockAcquireExtended: > /* > * Find or create lock and proclock entries with this tag > * > * Note: if the locallock object already existed, it might have a pointer > * to the lock already ... but we should not assume that that pointer is > * valid, since a lock object with zero hold and request counts can go > * away anytime. So we have to use SetupLockInTable() to recompute the > * lock and proclock pointers, even if they're already set. > */ > proclock = SetupLockInTable(lockMethodTable, MyProc, locktag, > hashcode, lockmode); So that comment suggests that the 'proclock' pointer cannot be trusted here. I don't remember how all this works, so I'm not sure if that is a show-stopper or if we could somehow leverage the 'proclock' pointer in LOCALLOCK anyway. - Heikki