v7-0003-Minimize-footprint-of-TOAST_MAX_CHUNK_SIZE-in-hea.patch
text/x-diff
Filename: v7-0003-Minimize-footprint-of-TOAST_MAX_CHUNK_SIZE-in-hea.patch
Type: text/x-diff
Part: 2
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 v7-0003
Subject: Minimize footprint of TOAST_MAX_CHUNK_SIZE in heap and amcheck
| File | + | − |
|---|---|---|
| contrib/amcheck/verify_heapam.c | 9 | 4 |
| src/backend/access/heap/heaptoast.c | 12 | 8 |
From b2d421d9e74de49ff73b229d93cd6de7e66751e8 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Wed, 13 Aug 2025 17:40:13 +0900
Subject: [PATCH v7 03/15] Minimize footprint of TOAST_MAX_CHUNK_SIZE in heap
and amcheck
This eases a follow-up change to support 8-byte TOAST value IDs, as the
maximum chunk size allowed for a single chunk of TOASTed data depends on
the size of the value ID.
---
src/backend/access/heap/heaptoast.c | 20 ++++++++++++--------
contrib/amcheck/verify_heapam.c | 13 +++++++++----
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c
index d4b600de3aca..a3933e48c8c8 100644
--- a/src/backend/access/heap/heaptoast.c
+++ b/src/backend/access/heap/heaptoast.c
@@ -634,11 +634,12 @@ heap_fetch_toast_slice(Relation toastrel, Oid8 valueid, int32 attrsize,
SysScanDesc toastscan;
HeapTuple ttup;
int32 expectedchunk;
- int32 totalchunks = ((attrsize - 1) / TOAST_MAX_CHUNK_SIZE) + 1;
+ int32 totalchunks;
int startchunk;
int endchunk;
int num_indexes;
int validIndex;
+ int32 max_chunk_size;
/* Look for the valid index of toast relation */
validIndex = toast_open_indexes(toastrel,
@@ -646,8 +647,11 @@ heap_fetch_toast_slice(Relation toastrel, Oid8 valueid, int32 attrsize,
&toastidxs,
&num_indexes);
- startchunk = sliceoffset / TOAST_MAX_CHUNK_SIZE;
- endchunk = (sliceoffset + slicelength - 1) / TOAST_MAX_CHUNK_SIZE;
+ max_chunk_size = TOAST_MAX_CHUNK_SIZE;
+
+ totalchunks = ((attrsize - 1) / max_chunk_size) + 1;
+ startchunk = sliceoffset / max_chunk_size;
+ endchunk = (sliceoffset + slicelength - 1) / max_chunk_size;
Assert(endchunk <= totalchunks);
/* Set up a scan key to fetch from the index. */
@@ -747,8 +751,8 @@ heap_fetch_toast_slice(Relation toastrel, Oid8 valueid, int32 attrsize,
curchunk,
startchunk, endchunk, valueid,
RelationGetRelationName(toastrel))));
- expected_size = curchunk < totalchunks - 1 ? TOAST_MAX_CHUNK_SIZE
- : attrsize - ((totalchunks - 1) * TOAST_MAX_CHUNK_SIZE);
+ expected_size = curchunk < totalchunks - 1 ? max_chunk_size
+ : attrsize - ((totalchunks - 1) * max_chunk_size);
if (chunksize != expected_size)
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
@@ -763,12 +767,12 @@ heap_fetch_toast_slice(Relation toastrel, Oid8 valueid, int32 attrsize,
chcpystrt = 0;
chcpyend = chunksize - 1;
if (curchunk == startchunk)
- chcpystrt = sliceoffset % TOAST_MAX_CHUNK_SIZE;
+ chcpystrt = sliceoffset % max_chunk_size;
if (curchunk == endchunk)
- chcpyend = (sliceoffset + slicelength - 1) % TOAST_MAX_CHUNK_SIZE;
+ chcpyend = (sliceoffset + slicelength - 1) % max_chunk_size;
memcpy(VARDATA(result) +
- (curchunk * TOAST_MAX_CHUNK_SIZE - sliceoffset) + chcpystrt,
+ (curchunk * max_chunk_size - sliceoffset) + chcpystrt,
chunkdata + chcpystrt,
(chcpyend - chcpystrt) + 1);
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index eb353c40249e..164ced37583a 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -1556,15 +1556,19 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
uint32 extsize)
{
int32 chunk_seq;
- int32 last_chunk_seq = (extsize - 1) / TOAST_MAX_CHUNK_SIZE;
+ int32 last_chunk_seq;
Pointer chunk;
bool isnull;
int32 chunksize;
int32 expected_size;
Oid8 toast_valueid;
+ int32 max_chunk_size;
toast_valueid = ta->toast_pointer.va_valueid;
+ max_chunk_size = TOAST_MAX_CHUNK_SIZE;
+ last_chunk_seq = (extsize - 1) / max_chunk_size;
+
/* Sanity-check the sequence number. */
chunk_seq = DatumGetInt32(fastgetattr(toasttup, 2,
ctx->toast_rel->rd_att, &isnull));
@@ -1629,8 +1633,8 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
return;
}
- expected_size = chunk_seq < last_chunk_seq ? TOAST_MAX_CHUNK_SIZE
- : extsize - (last_chunk_seq * TOAST_MAX_CHUNK_SIZE);
+ expected_size = chunk_seq < last_chunk_seq ? max_chunk_size
+ : extsize - (last_chunk_seq * max_chunk_size);
if (chunksize != expected_size)
report_toast_corruption(ctx, ta,
@@ -1872,9 +1876,10 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
int32 expected_chunk_seq = 0;
int32 last_chunk_seq;
Oid8 toast_valueid;
+ int32 max_chunk_size = TOAST_MAX_CHUNK_SIZE;
extsize = VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer);
- last_chunk_seq = (extsize - 1) / TOAST_MAX_CHUNK_SIZE;
+ last_chunk_seq = (extsize - 1) / max_chunk_size;
/*
* Setup a scan key to find chunks in toast table with matching va_valueid
--
2.51.0