HashAgg: release write buffers sooner by rewinding tape.
authorJeff Davis <jdavis@postgresql.org>
Wed, 16 Sep 2020 04:16:31 +0000 (21:16 -0700)
committerJeff Davis <jdavis@postgresql.org>
Wed, 16 Sep 2020 04:18:22 +0000 (21:18 -0700)
This was an oversight. The purpose of 7fdd919ae7 was to avoid keeping
tape buffers around unnecessisarily, but HashAgg didn't rewind early
enough.

Reviewed-by: Peter Geoghegan
Discussion: https://postgr.es/m/1fb1151c2cddf8747d14e0532da283c3f97e2685.camel@j-davis.com
Backpatch-through: 13

src/backend/executor/nodeAgg.c

index f74d4841f170dbdbc2c1e08aecfd59491876f706..28802e6588dbfdc131c7958e415371c352e0cd43 100644 (file)
@@ -2639,8 +2639,6 @@ agg_refill_hash_table(AggState *aggstate)
         */
        hashagg_recompile_expressions(aggstate, true, true);
 
-       LogicalTapeRewindForRead(tapeinfo->tapeset, batch->input_tapenum,
-                                                        HASHAGG_READ_BUFFER_SIZE);
        for (;;)
        {
                TupleTableSlot *spillslot = aggstate->hash_spill_rslot;
@@ -2923,6 +2921,7 @@ hashagg_tapeinfo_assign(HashTapeInfo *tapeinfo, int *partitions,
 static void
 hashagg_tapeinfo_release(HashTapeInfo *tapeinfo, int tapenum)
 {
+       /* rewinding frees the buffer while not in use */
        LogicalTapeRewindForWrite(tapeinfo->tapeset, tapenum);
        if (tapeinfo->freetapes_alloc == tapeinfo->nfreetapes)
        {
@@ -3152,6 +3151,7 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno)
 
        for (i = 0; i < spill->npartitions; i++)
        {
+               LogicalTapeSet  *tapeset = aggstate->hash_tapeinfo->tapeset;
                int                              tapenum = spill->partitions[i];
                HashAggBatch    *new_batch;
                double                   cardinality;
@@ -3163,9 +3163,13 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno)
                cardinality = estimateHyperLogLog(&spill->hll_card[i]);
                freeHyperLogLog(&spill->hll_card[i]);
 
-               new_batch = hashagg_batch_new(aggstate->hash_tapeinfo->tapeset,
-                                                                         tapenum, setno, spill->ntuples[i],
-                                                                         cardinality, used_bits);
+               /* rewinding frees the buffer while not in use */
+               LogicalTapeRewindForRead(tapeset, tapenum,
+                                                                HASHAGG_READ_BUFFER_SIZE);
+
+               new_batch = hashagg_batch_new(tapeset, tapenum, setno,
+                                                                         spill->ntuples[i], cardinality,
+                                                                         used_bits);
                aggstate->hash_batches = lcons(new_batch, aggstate->hash_batches);
                aggstate->hash_batches_used++;
        }