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 1vptDy-000jGW-2S for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Feb 2026 19:16:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vptCx-000fhw-0Q for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Feb 2026 19:15:35 +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 1vptCw-000fhn-2I for pgsql-hackers@lists.postgresql.org; Tue, 10 Feb 2026 19:15:35 +0000 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vptCu-000000000fL-2gdz for pgsql-hackers@postgresql.org; Tue, 10 Feb 2026 19:15:34 +0000 Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-48329eb96a7so21119955e9.3 for ; Tue, 10 Feb 2026 11:15:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770750930; x=1771355730; darn=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=5+gYm8+ztLRJFwLSrqkLatGLlw4lUK95kroGbRfgeRk=; b=mjCyqcPhFECWcksFloMPqpwi+Sb49GaMustsxyNYsf6jsFxn4JAUz0ODOOSXsGZ75c D/Zz1/iTOhuFDmSX2l8D3btCT8OC/D5EH1J6dwceSj/YxZbd8wuXeFyPZMlWzVhIavrJ NgTaXKBBhlXSGBCAa07dZQ6tLFJCBDHztCyvEsjZf0hdyfqKQ/CbR2BTdpHafPk4eUyJ /GCj9pnfE8o5cTcEJ2x6mJvB2DxVtH8b/lvrhCPLIQvtraS4YU4mbl0zThMjHFCXqCZQ aRzB13pF0SKB5EYCFGP1WCdCkvkNHKhFUCn9Rub1gXFUI7eRpzQYGgzOGH5xJnejLhbJ yGOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770750930; x=1771355730; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5+gYm8+ztLRJFwLSrqkLatGLlw4lUK95kroGbRfgeRk=; b=w7p7Ydt/hRP07u1eMh+1EHVuzOv1EvfR2T48veOjXrA2cXyOFh6tVlPsIOT0BUy7vJ +BGYurFHuX3CplPkyERlQmN5DoAxC+nBZAUxdgPe4mIuz1W4emhX/82CmQNmyXMicgh5 ziiM2qPtp0piRbIILe3AiclKErVMdr632lh+J8B7pWl06R6heOqunuJJCEUmhlHXP2bB g0mg5MRVELINqHjzc2I+l1stxpgLPYRJm6uj3aoBPhcaazwvPuPBQQtHcT+mnrDJfSSo 7vlbzcXYyZuIiE4HmwSEfpG/HPOIhD2wSfkhD5G0FoiMF3yrmSmZDHVmVTg9wTSqvWkp Cs6A== X-Forwarded-Encrypted: i=1; AJvYcCXqYvCJFHo1R5kDOfOyj31NOh6KcAq+fJ6bCBYE934TUASnxb21JnG6kAaaix7psvAMFcBjC0G2c9Lp5qU1@postgresql.org X-Gm-Message-State: AOJu0YzjXnm/7PXsklbTzGFIp90hz+x7J2mV4cC8G16orkCUVLgIt5dB 6OKFmmEml4j+DXEGgrzJcKiwoXxfdPKW4m9r5VJybGU2AmMFOP6eRkQT X-Gm-Gg: AZuq6aLg94DuLPAoNyvgVnV3uTu1uMCkRQsdJiyPxGc5Cl2tRh/C9vCIBTPDN5R5JPh Z8lqTY5Ye7VMl8m2MW9eR9IivJy6Ql93fxB26Vz1VTOUhLssHk3c4iMur0O1yOkWpFpB/TLdGNF HevarDxcJPIGLkocaOAb/2I6sOiiLCPJ4Cnpwwxv/1wGV058RtglG0ErOL5sIHSjnsDaqCY6Wss OCMx6naz0D/rr5CSYJ7c2+ySUbgDAZlTvOWifqtfli/14G7hdL4e3snsvVynVY8bJIcI2m+EpZV W66iPEyWy5yrRLdbgpvBHOIZdwp3A5l+WzrqKhTkuYGUX1qEXM4ApgL65yxxvxJmWkSgg5paIY2 DzQ6Gah8cH6ME711wwdU/wVgAKnrElZzqRZ94aMibcEMEGHdZXYKVUHLysvs6vWrj8LpVwdQs1u +EqrB0WGQT7fueT7E9oDqe7Bt1hVSD9a9e3r4piztidfaym7YNkUh3xKtP6xjEm6HRkEFnOkdHp uD7g5GYvzf8IyJjRhU01rQI+z7H89ugl3jl/gv+Mv9ykZfvqDV6aW6GUg== X-Received: by 2002:a05:600c:19d1:b0:477:9a28:b09a with SMTP id 5b1f17b1804b1-483208b9470mr227671785e9.0.1770750930204; Tue, 10 Feb 2026 11:15:30 -0800 (PST) Received: from ip-10-97-1-34.eu-west-3.compute.internal (ec2-15-237-197-144.eu-west-3.compute.amazonaws.com. [15.237.197.144]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4835a6114e3sm2065155e9.10.2026.02.10.11.15.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 11:15:29 -0800 (PST) Date: Tue, 10 Feb 2026 19:15:27 +0000 From: Bertrand Drouvot To: Andres Freund Cc: Heikki Linnakangas , "pgsql-hackers@postgresql.org" Subject: Re: PGPROC alignment (was Re: pgsql: Separate RecoveryConflictReasons from procsignals) Message-ID: References: <1cb0d7e9-d6dd-4517-a7cd-0ad98e1207f3@iki.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="pEfj2Sw+EscPkLsY" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --pEfj2Sw+EscPkLsY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, On Tue, Feb 10, 2026 at 01:15:01PM -0500, Andres Freund wrote: > Hi, > > On 2026-02-10 19:14:44 +0200, Heikki Linnakangas wrote: > Yea, I don't think we need to be perfect here. Just a bit less bad. And, as > you say, the current order doesn't make a lot of sense. > Just grouping things like > - pid, pgxactoff, backendType (i.e. barely if ever changing) > - wait_event_info, waitStart (i.e. very frequently changing, but typically > accessed within one proc) > - sem, lwWaiting, waitLockMode (i.e. stuff that is updated frequently and > accessed across processes) With an ordering like in the attached (to apply on top of Heikki's patch), we're back to 832 bytes. But, then the pg_attribute_aligned() added in Heikki's patch makes it 896 bytes... " /* 816 | 16 */ dlist_node lockGroupLink; /* XXX 64-byte padding */ /* total size (bytes): 896 */ } " What about applying this new ordering and remove the pg_attribute_aligned()? (I thought the aligned attribute would be smarter than that and not add this 64 padding bytes). Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com --pEfj2Sw+EscPkLsY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="order.txt" commit ea3aded2c4dec487c8a2ff5470cd7bae83e8dd47 Author: Bertrand Drouvot Date: Tue Feb 10 18:54:29 2026 +0000 reorder diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 53acce8a5a1..5d41301c966 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -184,29 +184,16 @@ typedef enum */ typedef struct PGPROC { - dlist_node links; /* list link if process is in a list */ - dlist_head *procgloballist; /* procglobal list that owns this PGPROC */ - - PGSemaphore sem; /* ONE semaphore to sleep on */ - ProcWaitStatus waitStatus; - - Latch procLatch; /* generic latch for process */ - - - TransactionId xid; /* id of top-level transaction currently being - * executed by this proc, if running and XID - * is assigned; else InvalidTransactionId. - * mirrored in ProcGlobal->xids[pgxactoff] */ - - TransactionId xmin; /* minimal running XID as it was when we were - * starting our xact, excluding LAZY VACUUM: - * vacuum must not remove tuples deleted by - * xid >= xmin ! */ - int pid; /* Backend's process ID; 0 if prepared xact */ - int pgxactoff; /* offset into various ProcGlobal->arrays with * data mirrored from this PGPROC */ + BackendType backendType; /* what kind of process is this? */ + + /* These fields are zero while a backend is still starting up: */ + Oid databaseId; /* OID of database this backend is using */ + Oid roleId; /* OID of role using this backend */ + Oid tempNamespaceId; /* OID of temp schema this backend is + * using */ /* * Currently running top-level transaction's virtual xid. Together these @@ -227,24 +214,44 @@ typedef struct PGPROC * InvalidLocalTransactionId */ } vxid; - /* These fields are zero while a backend is still starting up: */ - Oid databaseId; /* OID of database this backend is using */ - Oid roleId; /* OID of role using this backend */ + dlist_node links; /* list link if process is in a list */ + dlist_head *procgloballist; /* procglobal list that owns this PGPROC */ - Oid tempNamespaceId; /* OID of temp schema this backend is - * using */ + uint32 wait_event_info; /* proc's wait information */ + pg_atomic_uint64 waitStart; /* time at which wait for lock acquisition + * started */ - BackendType backendType; /* what kind of process is this? */ + TransactionId xid; /* id of top-level transaction currently being + * executed by this proc, if running and XID + * is assigned; else InvalidTransactionId. + * mirrored in ProcGlobal->xids[pgxactoff] */ - /* - * While in hot standby mode, shows that a conflict signal has been sent - * for the current transaction. Set/cleared while holding ProcArrayLock, - * though not required. Accessed without lock, if needed. - * - * This is a bitmask; each bit corresponds to a RecoveryConflictReason - * enum value. - */ - pg_atomic_uint32 pendingRecoveryConflicts; + TransactionId xmin; /* minimal running XID as it was when we were + * starting our xact, excluding LAZY VACUUM: + * vacuum must not remove tuples deleted by + * xid >= xmin ! */ + + ProcWaitStatus waitStatus; + int delayChkptFlags; /* for DELAY_CHKPT_* flags */ + + LOCKMODE waitLockMode; /* type of lock we're waiting for */ + LOCKMASK heldLocks; /* bitmask for lock types already held on this + * lock object by this backend */ + + uint8 statusFlags; /* this backend's status flags, see PROC_* + * above. mirrored in + * ProcGlobal->statusFlags[pgxactoff] */ + XidCacheStatus subxidStatus; /* mirrored with + * ProcGlobal->subxidStates[i] */ + + bool procArrayGroupMember; /* true, if member of ProcArray group + * waiting for XID clear */ + bool clogGroupMember; /* true, if member of clog group */ + bool fpVXIDLock; /* are we holding a fast-path VXID lock? */ + + LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID + * lock */ + PGSemaphore sem; /* ONE semaphore to sleep on */ /* * Info about LWLock the process is currently waiting for, if any. @@ -255,6 +262,19 @@ typedef struct PGPROC */ uint8 lwWaiting; /* see LWLockWaitState */ uint8 lwWaitMode; /* lwlock mode being waited for */ + + Latch procLatch; /* generic latch for process */ + + /* + * While in hot standby mode, shows that a conflict signal has been sent + * for the current transaction. Set/cleared while holding ProcArrayLock, + * though not required. Accessed without lock, if needed. + * + * This is a bitmask; each bit corresponds to a RecoveryConflictReason + * enum value. + */ + pg_atomic_uint32 pendingRecoveryConflicts; + proclist_node lwWaitLink; /* position in LW lock wait list */ /* Support for condition variables. */ @@ -264,17 +284,6 @@ typedef struct PGPROC /* waitLock and waitProcLock are NULL if not currently waiting. */ LOCK *waitLock; /* Lock object we're sleeping on ... */ PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */ - LOCKMODE waitLockMode; /* type of lock we're waiting for */ - LOCKMASK heldLocks; /* bitmask for lock types already held on this - * lock object by this backend */ - pg_atomic_uint64 waitStart; /* time at which wait for lock acquisition - * started */ - - int delayChkptFlags; /* for DELAY_CHKPT_* flags */ - - uint8 statusFlags; /* this backend's status flags, see PROC_* - * above. mirrored in - * ProcGlobal->statusFlags[pgxactoff] */ /* * Info to allow us to wait for synchronous replication, if needed. @@ -293,15 +302,11 @@ typedef struct PGPROC */ dlist_head myProcLocks[NUM_LOCK_PARTITIONS]; - XidCacheStatus subxidStatus; /* mirrored with - * ProcGlobal->subxidStates[i] */ struct XidCache subxids; /* cache for subtransaction XIDs */ /* Support for group XID clearing. */ - /* true, if member of ProcArray group waiting for XID clear */ - bool procArrayGroupMember; - /* next ProcArray group member waiting for XID clear */ - pg_atomic_uint32 procArrayGroupNext; + pg_atomic_uint32 procArrayGroupNext; /* next ProcArray group member + * waiting for XID clear */ /* * latest transaction id among the transaction's main XID and @@ -309,10 +314,7 @@ typedef struct PGPROC */ TransactionId procArrayGroupMemberXid; - uint32 wait_event_info; /* proc's wait information */ - /* Support for group transaction status update. */ - bool clogGroupMember; /* true, if member of clog group */ pg_atomic_uint32 clogGroupNext; /* next clog group member */ TransactionId clogGroupMemberXid; /* transaction id of clog group member */ XidStatus clogGroupMemberXidStatus; /* transaction status of clog @@ -326,9 +328,6 @@ typedef struct PGPROC LWLock fpInfoLock; /* protects per-backend fast-path state */ uint64 *fpLockBits; /* lock modes held for each fast-path slot */ Oid *fpRelId; /* slots for rel oids */ - bool fpVXIDLock; /* are we holding a fast-path VXID lock? */ - LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID - * lock */ /* * Support for lock groups. Use LockHashPartitionLockByProc on the group --pEfj2Sw+EscPkLsY--