0001-BRIN-Prevent-the-heapblk-overflow-during-index-summa.patch
application/octet-stream
Filename: 0001-BRIN-Prevent-the-heapblk-overflow-during-index-summa.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: BRIN: Prevent the heapblk overflow during index summarization on very large tables
| File | + | − |
|---|---|---|
| src/backend/access/brin/brin.c | 2 | 2 |
From f0a59c18ecb068bbf417c9a8c8cbbcc37460dd3f Mon Sep 17 00:00:00 2001
From: Sunil Seetharama <sunil.s@broadcom.com>
Date: Fri, 17 Oct 2025 10:51:42 +0530
Subject: [PATCH] BRIN: Prevent the heapblk overflow during index summarization
on very large tables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Previously, `heapBlk` was defined as an unsigned 32-bit integer. When incremented
by `pagesPerRange` on very large tables, it could wrap around, causing the condition
`heapBlk < nblocks` to remain true indefinitely — resulting in an infinite loop.
This could cause the PostgreSQL backend to hang, consuming 100% CPU indefinitely
and preventing operations from completing on large tables.
The solution is straightforward — the data type of `heapBlk` has been changed
from a 32-bit integer to a 64-bit `BlockNumber` (int64), ensuring it can safely
handle extremely large tables without risk of overflow.
This was explained very nicely by Tomas Vondra[1] and below two solutions were
suggested.
i) Change to int64
ii) Tracking the prevHeapBlk
Among these two I feel using solution #1 would be more feasible(similar to previously used solution #2), though
other solution also works.
Reference:
[1] https://www.postgresql.org/message-id/b8a4e04c-c091-056c-a379-11d35c7b2d8d%40enterprisedb.com
[2] https://github.com/postgres/postgres/commit/4bc6fb57f774ea18187fd8565aad9994160bfc17
---
src/backend/access/brin/brin.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 7ff7467e462..6a273e9fc39 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -573,7 +573,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
Relation heapRel;
BrinOpaque *opaque;
BlockNumber nblocks;
- BlockNumber heapBlk;
+ int64 heapBlk;
int64 totalpages = 0;
FmgrInfo *consistentFn;
MemoryContext oldcxt;
@@ -749,7 +749,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
MemoryContextReset(perRangeCxt);
- tup = brinGetTupleForHeapBlock(opaque->bo_rmAccess, heapBlk, &buf,
+ tup = brinGetTupleForHeapBlock(opaque->bo_rmAccess, (BlockNumber )heapBlk, &buf,
&off, &size, BUFFER_LOCK_SHARE);
if (tup)
{
--
2.50.1