summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2023-01-26 01:50:07 +0000
committerThomas Munro2023-01-26 01:52:19 +0000
commitffcf6f4cfca5a4ce2ac7ff7e8fa17541a5a9caea (patch)
tree416e857ce53e6dc7a65e5c0be90c73969270dff7
parent9aeff092c05820d6a9252d7a3f8db86f71f2205f (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 e3da83f10be..08312491599 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;