Hi,
On Tue, 31 Mar 2026 at 13:19, Christoph Berg <[email protected]> wrote:
>
> One of the AIO commits around this one (2026-03-28 00:00Z) broke the
> postgresql-19 builds on apt.pg.o. Only the Debian unstable (sid,
> assertions enabled) builds are working, everything else including the
> nearly identical testing (forky) is broken (where assertions are off):
Thank you for the report! I can reproduce this when I disable
assertions. The problem is that, in StartReadBuffersImpl() in
bufmgr.c:
```
#ifdef USE_ASSERT_CHECKING
/*
* Initialize enough of ReadBuffersOperation to make
* CheckReadBuffersOperation() work. Outside of assertions
* that's not necessary when no IO is issued.
*/
operation->buffers = buffers;
operation->blocknum = blockNum;
operation->nblocks = 1;
operation->nblocks_done = 1;
CheckReadBuffersOperation(operation, true);
#endif
```
if (found) and if (i == 0) then we set operation->buffers and
operation->nblocks if the assertions are enabled but AIO tests expect
to read these values. So, read_buffers() in AIO tests read incorrect
values [1] when the assertions are disabled. Moving operation->buffers
and operation->nblocks outside of #ifdef USE_ASSERT_CHECKING like in
the attached fixes the problem.
[1]
read_buffers(PG_FUNCTION_ARGS)
{
...
for (int nio = 0; nio < nios; nio++)
{
ReadBuffersOperation *operation = &operations[nio];
int nblocks_this_io = operation->nblocks;
Datum values[6] = {0};
bool nulls[6] = {0};
ArrayType *buffers_arr;
/* convert buffer array to datum array */
for (int i = 0; i < nblocks_this_io; i++)
{
Buffer buf = operation->buffers[i];
...
}
--
Regards,
Nazir Bilal Yavuz
Microsoft
From 56218fc850cdaccaeb87767c2ca8977ee2f26697 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email protected]>
Date: Tue, 31 Mar 2026 15:00:40 +0300
Subject: [PATCH] Set the variables that callers might read in
StartReadBuffersImpl()
When the first requested block is already in the buffer pool, StartRead-
BuffersImpl() returned early after setting *nblocks = 1 without starting
any I/O. In that path, operation->nblocks and operation->buffers were
only initialised inside #ifdef USE_ASSERT_CHECKING, leaving them as zero
/ NULL in non-assert builds.
Callers might want to inspect these values like in the AIO tests. Fix
that problem by unconditionally setting operation->nblocks and
operation->buffers in the early-return hit path.
---
src/backend/storage/buffer/bufmgr.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index cd21ae3fc36..e6f99ad7668 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -1457,6 +1457,10 @@ StartReadBuffersImpl(ReadBuffersOperation *operation,
{
*nblocks = 1;
+ /* Set the variables that callers might read */
+ operation->buffers = buffers;
+ operation->nblocks = 1;
+
#ifdef USE_ASSERT_CHECKING
/*
@@ -1464,9 +1468,7 @@ StartReadBuffersImpl(ReadBuffersOperation *operation,
* CheckReadBuffersOperation() work. Outside of assertions
* that's not necessary when no IO is issued.
*/
- operation->buffers = buffers;
operation->blocknum = blockNum;
- operation->nblocks = 1;
operation->nblocks_done = 1;
CheckReadBuffersOperation(operation, true);
#endif
--
2.47.3