Hi,

While running parallel vacuum with track_cost_delay_timing=on, I
noticed memory in the parallel worker process keeps growing
proportionally to vacuum runtime, and is never reclaimed until the
worker exits.

I think pgstat_progress_parallel_incr_param() (backend_progress.c)
leaks memory on every call from a parallel worker.

The suspected block:

    static StringInfoData progress_message;
    initStringInfo(&progress_message);                /* palloc -> A   */
    pq_beginmessage(&progress_message, PqMsg_Progress);
    /* pq_beginmessage internally calls initStringInfo again ->
       palloc -> B, A is orphaned                                       */
    pq_sendint32(&progress_message, index);
    pq_sendint64(&progress_message, incr);
    pq_endmessage(&progress_message);                 /* pfree(B), A leaked
*/

So one palloc(~1 kB) leaks per call, into the per-worker context.

This is an oversight of f1889729dd3 ("Add new parallel message type
to progress reporting"); track_cost_delay_timing just makes it more
visible.  With that GUC enabled, a long-running parallel vacuum leaks
megabytes per worker (~232 MB observed in a 43-min vacuum at default
settings on a 15M-row, 30-index workload).

The proposed fix is in the attached patch which does a one-time init of the
static
buffer, then pq_beginmessage_reuse() / pq_endmessage_reuse() so the
buffer is allocated once and reused.

All 245 regression tests pass.

Thanks,
Baji Shaik.

Attachment: 0001-Fix-memory-leak-in-pgstat_progress_parallel_incr_par.patch
Description: Binary data

Reply via email to