Commit faeedbcefd4 changed the alignment of WAL buffers from XLOG_BLCKSZ
to PG_IO_ALIGN_SIZE.
While looking around for places to apply alignas, I think I found at
least two places that were forgotten, namely in BootStrapXLOG() and in
pg_test_fsync.c. Patches attached for those.
I also suspect that the TYPEALIGN call in XLOGShmemInit() should take
PG_IO_ALIGN_SIZE into account, but it's not immediately obvious how,
since the comment also mentions that it wants alignment on "a full xlog
block size boundary". Maybe Max(XLOG_BLCKSZ, PG_IO_ALIGN_SIZE)?
I also wonder whether the check in check_debug_io_direct() for #if
XLOG_BLCKSZ < PG_IO_ALIGN_SIZE would be required if we fixed all those
places?
From ff51fe7b0cf210f58549c1c3b67bd3175de2e8f7 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 1 Dec 2025 08:06:26 +0100
Subject: [PATCH 1/3] Use PG_IO_ALIGN_SIZE for aligning WAL buffers
There are two places that were apparently forgotten in commit faeedbcefd4.
---
src/backend/access/transam/xlog.c | 4 ++--
src/bin/pg_test_fsync/pg_test_fsync.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/backend/access/transam/xlog.c
b/src/backend/access/transam/xlog.c
index 22d0a2e8c3a..44e1d4eeabd 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5119,8 +5119,8 @@ BootStrapXLOG(uint32 data_checksum_version)
sysidentifier |= getpid() & 0xFFF;
/* page buffer must be aligned suitably for O_DIRECT */
- buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
- page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
+ buffer = (char *) palloc(XLOG_BLCKSZ + PG_IO_ALIGN_SIZE);
+ page = (XLogPageHeader) TYPEALIGN(PG_IO_ALIGN_SIZE, buffer);
memset(page, 0, XLOG_BLCKSZ);
/*
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c
b/src/bin/pg_test_fsync/pg_test_fsync.c
index 0060ea15902..a63d6f1a54f 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -234,7 +234,7 @@ prepare_buf(void)
for (ops = 0; ops < DEFAULT_XLOG_SEG_SIZE; ops++)
full_buf[ops] = (char) pg_prng_int32(&pg_global_prng_state);
- buf = (char *) TYPEALIGN(XLOG_BLCKSZ, full_buf);
+ buf = (char *) TYPEALIGN(PG_IO_ALIGN_SIZE, full_buf);
}
static void
base-commit: d03668ea0566b53522cf2628ab7aa630247640a4
--
2.52.0
From ee89bc0b07725adc3dc9c61df15fc2e87e8eb353 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 1 Dec 2025 08:06:26 +0100
Subject: [PATCH 2/3] Use PGAlignedXLogBlock in BootStrapXLOG()
for code simplification
---
src/backend/access/transam/xlog.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/backend/access/transam/xlog.c
b/src/backend/access/transam/xlog.c
index 44e1d4eeabd..89cbda9cc7c 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5089,7 +5089,7 @@ void
BootStrapXLOG(uint32 data_checksum_version)
{
CheckPoint checkPoint;
- char *buffer;
+ PGAlignedXLogBlock buffer;
XLogPageHeader page;
XLogLongPageHeader longpage;
XLogRecord *record;
@@ -5118,10 +5118,8 @@ BootStrapXLOG(uint32 data_checksum_version)
sysidentifier |= ((uint64) tv.tv_usec) << 12;
sysidentifier |= getpid() & 0xFFF;
- /* page buffer must be aligned suitably for O_DIRECT */
- buffer = (char *) palloc(XLOG_BLCKSZ + PG_IO_ALIGN_SIZE);
- page = (XLogPageHeader) TYPEALIGN(PG_IO_ALIGN_SIZE, buffer);
- memset(page, 0, XLOG_BLCKSZ);
+ memset(&buffer, 0, sizeof buffer);
+ page = (XLogPageHeader) &buffer;
/*
* Set up information for the initial checkpoint record
@@ -5202,7 +5200,7 @@ BootStrapXLOG(uint32 data_checksum_version)
/* Write the first page with the initial record */
errno = 0;
pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
- if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+ if (write(openLogFile, &buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
@@ -5242,8 +5240,6 @@ BootStrapXLOG(uint32 data_checksum_version)
BootStrapSUBTRANS();
BootStrapMultiXact();
- pfree(buffer);
-
/*
* Force control file to be read - in contrast to normal processing we'd
* otherwise never run the checks and GUC related initializations
therein.
--
2.52.0
From 7823bceebb9188d6817b8bc6516f4c6a8828033b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 1 Dec 2025 08:18:16 +0100
Subject: [PATCH 3/3] pg_test_fsync: Align test data using PGAlignedXLogBlock
for code simplification
---
src/bin/pg_test_fsync/pg_test_fsync.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c
b/src/bin/pg_test_fsync/pg_test_fsync.c
index a63d6f1a54f..3d0c242cc20 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -68,9 +68,8 @@ static const char *progname;
static unsigned int secs_per_test = 5;
static int needs_unlink = 0;
-static char full_buf[DEFAULT_XLOG_SEG_SIZE],
- *buf,
- *filename = FSYNC_FILENAME;
+static alignas(PGAlignedXLogBlock) char buf[DEFAULT_XLOG_SEG_SIZE];
+static char *filename = FSYNC_FILENAME;
static struct timeval start_t,
stop_t;
static sig_atomic_t alarm_triggered = false;
@@ -232,9 +231,7 @@ prepare_buf(void)
/* write random data into buffer */
for (ops = 0; ops < DEFAULT_XLOG_SEG_SIZE; ops++)
- full_buf[ops] = (char) pg_prng_int32(&pg_global_prng_state);
-
- buf = (char *) TYPEALIGN(PG_IO_ALIGN_SIZE, full_buf);
+ buf[ops] = (char) pg_prng_int32(&pg_global_prng_state);
}
static void
@@ -248,7 +245,7 @@ test_open(void)
if ((tmpfile = open(filename, O_RDWR | O_CREAT | PG_BINARY, S_IRUSR |
S_IWUSR)) == -1)
die("could not open output file");
needs_unlink = 1;
- if (write(tmpfile, full_buf, DEFAULT_XLOG_SEG_SIZE) !=
+ if (write(tmpfile, buf, DEFAULT_XLOG_SEG_SIZE) !=
DEFAULT_XLOG_SEG_SIZE)
die("write failed");
--
2.52.0