From b0e06a6669de625d6226720a8b73ff130ea23ade Mon Sep 17 00:00:00 2001
From: Thomas Munro
Date: Sat, 24 Sep 2022 08:55:20 +1200
Subject: [PATCH 2/2] Fix sharedtuplestore.c corruption.
If the final chunk of an oversized tuple being written out to disk was
exactly 32760 bytes, it would be corrupted due to a fencepost bug.
Bug #17619. Back-patch to 11 where the code arrived.
While testing that, I (tmunro) noticed that the per-participant page
counter was not initialized to zero as it should have been; that wasn't
a live bug when it was written since DSM memory was originally always
zeroed, but since 14 min_dynamic_shared_memory might be configured and
it supplies non-zeroed memory, so that is also fixed here.
Author: Dmitry Astapov
Discussion: https://postgr.es/m/17619-0de62ceda812b8b5%40postgresql.org
---
src/backend/utils/sort/sharedtuplestore.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index 996cef07d4..464d4c5b7f 100644
--- a/src/backend/utils/sort/sharedtuplestore.c
+++ b/src/backend/utils/sort/sharedtuplestore.c
@@ -158,6 +158,7 @@ sts_initialize(SharedTuplestore *sts, int participants,
LWLockInitialize(&sts->participants[i].lock,
LWTRANCHE_SHARED_TUPLESTORE);
sts->participants[i].read_page = 0;
+ sts->participants[i].npages = 0;
sts->participants[i].writing = false;
}
@@ -320,7 +321,7 @@ sts_puttuple(SharedTuplestoreAccessor *accessor, void *meta_data,
/* Do we have space? */
size = accessor->sts->meta_data_size + tuple->t_len;
- if (accessor->write_pointer + size >= accessor->write_end)
+ if (accessor->write_pointer + size > accessor->write_end)
{
if (accessor->write_chunk == NULL)
{
@@ -340,7 +341,7 @@ sts_puttuple(SharedTuplestoreAccessor *accessor, void *meta_data,
}
/* It may still not be enough in the case of a gigantic tuple. */
- if (accessor->write_pointer + size >= accessor->write_end)
+ if (accessor->write_pointer + size > accessor->write_end)
{
size_t written;
--
2.30.2