public inbox for [email protected]
help / color / mirror / Atom feedFrom: Heikki Linnakangas <[email protected]>
To: Bertrand Drouvot <[email protected]>
Cc: Andres Freund <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: PGPROC alignment (was Re: pgsql: Separate RecoveryConflictReasons from procsignals)
Date: Wed, 11 Feb 2026 12:03:51 +0200
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
On 11/02/2026 06:40, Bertrand Drouvot wrote:
> A few comments:
>
> 0001:
>
> + * and (b) to make the multiplication / division to convert between PGPROC *
> + * and ProcNumber be a little cheaper
>
> Is that correct if PGPROC size is not a power of 2?
You're right, it's not.
> 0002: Good catch!
Committed that.
>> With this, sizeof(PGPROC) == 864 without the explicit alignment to
>> PG_CACHE_LINE_SIZE, and 896 with it.
>
> I can see 876 -> 896 on my side:
>
> /* 872 | 4 */ uint32 wait_event_info;
> /* XXX 20-byte padding */
>
> /* total size (bytes): 896 */
> }
Interesting. I've attached 'pahole bin/postgres' output from my laptop.
It's Linux on arm64. This is with my v2 patches to rearrange the fields,
but with the "pg_attribute_aligned(PG_CACHE_LINE_SIZE)" removed.
- Heikki
struct PGPROC {
dlist_head * procgloballist; /* 0 8 */
dlist_node freeProcsLink; /* 8 16 */
int pid; /* 24 4 */
BackendType backendType; /* 28 4 */
Oid databaseId; /* 32 4 */
Oid roleId; /* 36 4 */
Oid tempNamespaceId; /* 40 4 */
int pgxactoff; /* 44 4 */
uint8 statusFlags; /* 48 1 */
/* XXX 3 bytes hole, try to pack */
struct {
ProcNumber procNumber; /* 52 4 */
LocalTransactionId lxid; /* 56 4 */
} vxid; /* 52 8 */
TransactionId xid; /* 60 4 */
/* --- cacheline 1 boundary (64 bytes) --- */
TransactionId xmin; /* 64 4 */
XidCacheStatus subxidStatus; /* 68 2 */
/* XXX 2 bytes hole, try to pack */
struct XidCache subxids; /* 72 256 */
/* --- cacheline 5 boundary (320 bytes) was 8 bytes ago --- */
Latch procLatch; /* 328 16 */
PGSemaphore sem; /* 344 8 */
int delayChkptFlags; /* 352 4 */
pg_atomic_uint32 pendingRecoveryConflicts; /* 356 4 */
uint8 lwWaiting; /* 360 1 */
uint8 lwWaitMode; /* 361 1 */
/* XXX 2 bytes hole, try to pack */
proclist_node lwWaitLink; /* 364 8 */
proclist_node cvWaitLink; /* 372 8 */
/* XXX 4 bytes hole, try to pack */
/* --- cacheline 6 boundary (384 bytes) --- */
PGPROC * lockGroupLeader; /* 384 8 */
dlist_head lockGroupMembers; /* 392 16 */
dlist_node lockGroupLink; /* 408 16 */
LOCK * waitLock; /* 424 8 */
dlist_node waitLink; /* 432 16 */
/* --- cacheline 7 boundary (448 bytes) --- */
PROCLOCK * waitProcLock; /* 448 8 */
LOCKMODE waitLockMode; /* 456 4 */
LOCKMASK heldLocks; /* 460 4 */
pg_atomic_uint64 waitStart __attribute__((__aligned__(8))); /* 464 8 */
ProcWaitStatus waitStatus; /* 472 4 */
/* XXX 4 bytes hole, try to pack */
dlist_head myProcLocks[16]; /* 480 256 */
/* --- cacheline 11 boundary (704 bytes) was 32 bytes ago --- */
LWLock fpInfoLock; /* 736 16 */
uint64 * fpLockBits; /* 752 8 */
Oid * fpRelId; /* 760 8 */
/* --- cacheline 12 boundary (768 bytes) --- */
_Bool fpVXIDLock; /* 768 1 */
/* XXX 3 bytes hole, try to pack */
LocalTransactionId fpLocalTransactionId; /* 772 4 */
XLogRecPtr waitLSN; /* 776 8 */
int syncRepState; /* 784 4 */
/* XXX 4 bytes hole, try to pack */
dlist_node syncRepLinks; /* 792 16 */
_Bool procArrayGroupMember; /* 808 1 */
/* XXX 3 bytes hole, try to pack */
pg_atomic_uint32 procArrayGroupNext; /* 812 4 */
TransactionId procArrayGroupMemberXid; /* 816 4 */
_Bool clogGroupMember; /* 820 1 */
/* XXX 3 bytes hole, try to pack */
pg_atomic_uint32 clogGroupNext; /* 824 4 */
TransactionId clogGroupMemberXid; /* 828 4 */
/* --- cacheline 13 boundary (832 bytes) --- */
XidStatus clogGroupMemberXidStatus; /* 832 4 */
/* XXX 4 bytes hole, try to pack */
int64 clogGroupMemberPage; /* 840 8 */
XLogRecPtr clogGroupMemberLsn; /* 848 8 */
uint32 wait_event_info; /* 856 4 */
/* size: 864, cachelines: 14, members: 51 */
/* sum members: 828, holes: 10, sum holes: 32 */
/* padding: 4 */
/* forced alignments: 1 */
/* last cacheline: 32 bytes */
} __attribute__((__aligned__(8)));
Attachments:
[text/plain] pahole-PGPROC.txt (4.5K, 2-pahole-PGPROC.txt)
download | inline:
struct PGPROC {
dlist_head * procgloballist; /* 0 8 */
dlist_node freeProcsLink; /* 8 16 */
int pid; /* 24 4 */
BackendType backendType; /* 28 4 */
Oid databaseId; /* 32 4 */
Oid roleId; /* 36 4 */
Oid tempNamespaceId; /* 40 4 */
int pgxactoff; /* 44 4 */
uint8 statusFlags; /* 48 1 */
/* XXX 3 bytes hole, try to pack */
struct {
ProcNumber procNumber; /* 52 4 */
LocalTransactionId lxid; /* 56 4 */
} vxid; /* 52 8 */
TransactionId xid; /* 60 4 */
/* --- cacheline 1 boundary (64 bytes) --- */
TransactionId xmin; /* 64 4 */
XidCacheStatus subxidStatus; /* 68 2 */
/* XXX 2 bytes hole, try to pack */
struct XidCache subxids; /* 72 256 */
/* --- cacheline 5 boundary (320 bytes) was 8 bytes ago --- */
Latch procLatch; /* 328 16 */
PGSemaphore sem; /* 344 8 */
int delayChkptFlags; /* 352 4 */
pg_atomic_uint32 pendingRecoveryConflicts; /* 356 4 */
uint8 lwWaiting; /* 360 1 */
uint8 lwWaitMode; /* 361 1 */
/* XXX 2 bytes hole, try to pack */
proclist_node lwWaitLink; /* 364 8 */
proclist_node cvWaitLink; /* 372 8 */
/* XXX 4 bytes hole, try to pack */
/* --- cacheline 6 boundary (384 bytes) --- */
PGPROC * lockGroupLeader; /* 384 8 */
dlist_head lockGroupMembers; /* 392 16 */
dlist_node lockGroupLink; /* 408 16 */
LOCK * waitLock; /* 424 8 */
dlist_node waitLink; /* 432 16 */
/* --- cacheline 7 boundary (448 bytes) --- */
PROCLOCK * waitProcLock; /* 448 8 */
LOCKMODE waitLockMode; /* 456 4 */
LOCKMASK heldLocks; /* 460 4 */
pg_atomic_uint64 waitStart __attribute__((__aligned__(8))); /* 464 8 */
ProcWaitStatus waitStatus; /* 472 4 */
/* XXX 4 bytes hole, try to pack */
dlist_head myProcLocks[16]; /* 480 256 */
/* --- cacheline 11 boundary (704 bytes) was 32 bytes ago --- */
LWLock fpInfoLock; /* 736 16 */
uint64 * fpLockBits; /* 752 8 */
Oid * fpRelId; /* 760 8 */
/* --- cacheline 12 boundary (768 bytes) --- */
_Bool fpVXIDLock; /* 768 1 */
/* XXX 3 bytes hole, try to pack */
LocalTransactionId fpLocalTransactionId; /* 772 4 */
XLogRecPtr waitLSN; /* 776 8 */
int syncRepState; /* 784 4 */
/* XXX 4 bytes hole, try to pack */
dlist_node syncRepLinks; /* 792 16 */
_Bool procArrayGroupMember; /* 808 1 */
/* XXX 3 bytes hole, try to pack */
pg_atomic_uint32 procArrayGroupNext; /* 812 4 */
TransactionId procArrayGroupMemberXid; /* 816 4 */
_Bool clogGroupMember; /* 820 1 */
/* XXX 3 bytes hole, try to pack */
pg_atomic_uint32 clogGroupNext; /* 824 4 */
TransactionId clogGroupMemberXid; /* 828 4 */
/* --- cacheline 13 boundary (832 bytes) --- */
XidStatus clogGroupMemberXidStatus; /* 832 4 */
/* XXX 4 bytes hole, try to pack */
int64 clogGroupMemberPage; /* 840 8 */
XLogRecPtr clogGroupMemberLsn; /* 848 8 */
uint32 wait_event_info; /* 856 4 */
/* size: 864, cachelines: 14, members: 51 */
/* sum members: 828, holes: 10, sum holes: 32 */
/* padding: 4 */
/* forced alignments: 1 */
/* last cacheline: 32 bytes */
} __attribute__((__aligned__(8)));
view thread (22+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Subject: Re: PGPROC alignment (was Re: pgsql: Separate RecoveryConflictReasons from procsignals)
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox