0

I was scanning the source code of pgSQL and found an interesting macro.

#define SizeOfXLogRecord    (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c))

The definition of the XLogRecord is

typedef struct XLogRecord
{
    uint32      xl_tot_len;     /* total len of entire record */
    TransactionId xl_xid;       /* xact id */
    XLogRecPtr  xl_prev;        /* ptr to previous record in log */
    uint8       xl_info;        /* flag bits, see below */
    RmgrId      xl_rmid;        /* resource manager for this record */
    /* 2 bytes of padding here, initialize to zero */
    pg_crc32c   xl_crc;         /* CRC for this record */

    /* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */

} XLogRecord;

I am confused about why the micro uses the sum of offsetof of the last member and the sizeof the last member to define the size of the stuct? Would there be any difference if I directly use sizeof of the struct?

By the way, what is the size of the struct XLogRecord? I think it's 24 bytes because of memory alignment. But I saw from here that the size is 32 bytes (pciture here). Can someone also explain this?
Update: the size of XLogRecord varies from versions. In the latest version this size is exactly 24 bytes.

Any help or information will be appreciated.

The code is an excerpt from https://github.com/postgres/postgres/blob/4035cd5d4eee4dae797bfc77ab07f8dcd8781b41/src/include/access/xlogrecord.h

lumos
  • 1
  • 3
  • I think the idea is that the ```XLogRecord``` struct overlays a block of memory where additional data follows the struct (the ```XLogRecordBlockHeaders``` mentioned in the struct comment). ```sizeof(XlogRecord)``` might give a misleading offset to ```XLogRecordBlockHeaders``` if the compiler would otherwise add padding after ```xl_crc```. ```offsetof + sizeof``` won't have that problem. – sj95126 Aug 10 '21 at 03:28
  • From version 9.5 or later, the size of `XLogRecord` has been changed to 24 bytes. Have updated the post. Thanks for @sj95126 's explanation. To my understanding, the complier won't add padding after the `XLogRecord`. Because the size of the struct is 24 bytes and the largest member is 8 bytes (`TransactionId`). I think it is already aligned. Also according to @sj95126, if we do so to fix the padding which is added by the complier, does it mean we intentionally omit the memory alignment mechanism? Sacrifice performance to decrease the memory? – lumos Aug 10 '21 at 08:35

0 Answers0