From 013c382132de8e56f5bce4c0622c609c45aa2a4e Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Mon, 14 Sep 2020 14:18:49 -0700 Subject: [PATCH] LogicalTapeSetBlocks issue: Tentative fix --- src/backend/utils/sort/logtape.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index d6d1e1911e..828d5463f2 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -245,7 +245,8 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) * end of file and the target block with zeros. * * This can happen either when tapes preallocate blocks; or for the last - * block of a tape which might not have been flushed. + * block of a tape which might not have been flushed. See + * LogicalTapeSetBlocks() comments. * * Note that BufFile concatenation can leave "holes" in BufFile between * worker-owned block ranges. These are tracked for reporting purposes @@ -549,6 +550,7 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, /* Should have at least one worker tape, plus leader's tape */ Assert(lts->nTapes >= 2); + Assert(!lts->enable_prealloc); /* * Build concatenated view of all BufFiles, remembering the block number @@ -1268,5 +1270,22 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum, long LogicalTapeSetBlocks(LogicalTapeSet *lts) { + /* + * When we use preallocation the number of blocks allocated can noticeably + * exceed the number of blocks actually written to temp file, so report + * blocks written to caller. Otherwise, report number of blocks allocated + * less number of hole blocks. + * + * nBlocksWritten usually has the same value as nBlocksAllocated when + * preallocation is disabled. Allocating one block ahead of a written + * block is occasionally necessary when the last block of a tape hasn't + * been flushed, so it seems like a good idea to use nBlocksAllocated -- + * it will be the "final" number of blocks written when we actually flush. + * (In practice this probably doesn't matter because we'll be called after + * the flush anyway, but be tidy.) + */ + if (lts->enable_prealloc) + return lts->nBlocksWritten; + return lts->nBlocksAllocated - lts->nHoleBlocks; } -- 2.25.1