summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2023-01-26 14:50:07 +1300
committerThomas Munro <tmunro@postgresql.org>2023-01-26 14:53:37 +1300
commitd9f5345bf90799a992995d935b712e5040830732 (patch)
tree3614ed8a66bce39f6744ba623ae8dfa724174af9
parent88c27b8fe201fe197ef988f0910f282015ea767c (diff)
Fix rare 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 (see test module in archives), 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 <dastapov@gmail.com> Discussion: https://postgr.es/m/17619-0de62ceda812b8b5%40postgresql.org
-rw-r--r--src/backend/utils/sort/sharedtuplestore.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index 996cef07d4f..464d4c5b7fd 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;