HashAgg: release write buffers sooner by rewinding tape.
authorJeff Davis <[email protected]>
Wed, 16 Sep 2020 04:16:31 +0000 (21:16 -0700)
committerJeff Davis <[email protected]>
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[email protected]
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++;
    }