mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Minimize footprint of TOAST_MAX_CHUNK_SIZE in heap and amcheck code
This refactoring eases a little bit a follow-up change to add support for 8-byte TOAST value IDs, as the maximum chunk size allowed for a single chunk of TOASTed data depends on the size of varatt_external, its value ID being part of it. It is worth noting that TOAST_MAX_CHUNK_SIZE resolves as a uintptr_t, so the previous calculations were in 64-bit unsigned arithmetic. These are now done in int32, which still works the same way due to an external TOAST value being bounded to 1GB. Author: Michael Paquier <michael@paquier.xyz> Reviewed-by: Yugo Nagata <nagata@sraoss.co.jp> Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Discussion: https://postgr.es/m/CALj2ACVnO6jjs5aRx3dSOBy9LV7=iakPBR1eOvoeB8rL8Q47zg@mail.gmail.com
This commit is contained in:
@@ -1558,11 +1558,15 @@ 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;
|
||||
int32 max_chunk_size;
|
||||
|
||||
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,
|
||||
@@ -1628,8 +1632,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,
|
||||
@@ -1868,9 +1872,10 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
|
||||
uint32 extsize;
|
||||
int32 expected_chunk_seq = 0;
|
||||
int32 last_chunk_seq;
|
||||
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
|
||||
|
||||
@@ -634,11 +634,12 @@ heap_fetch_toast_slice(Relation toastrel, Oid 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, Oid 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, Oid 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, Oid 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user