Hi,

When a REPACK (CONCURRENTLY) session is terminated via
pg_terminate_backend(), the REPACK decoding worker keeps running
indefinitely and holds its temporary replication slot.

To reproduce:

  -- Session 1: start a long REPACK
  REPACK (CONCURRENTLY) big_table;

  -- Session 2: kill it
  SELECT pg_terminate_backend(pid)
  FROM pg_stat_activity
  WHERE query LIKE '%REPACK%';

  -- The slot persists:
  SELECT slot_name, active FROM pg_replication_slots;
  -- repack_NNNN | t   (still active, cannot be dropped)

Root cause:

pg_terminate_backend() causes ereport(FATAL) via ProcDiePending.
FATAL exits bypass PG_FINALLY blocks, so stop_repack_decoding_worker()
is never called. The decoding worker is left running.

Fix:

Register an on_proc_exit callback when the decoding worker starts.
The callback calls TerminateBackgroundWorker() to signal the worker.
We do not wait for the worker to exit in the callback (WaitLatch is
not safe during proc_exit); the worker's RS_TEMPORARY slot is dropped
automatically when the worker process exits.

Thanks,
Baji Shaik
AWS RDS

Attachment: 0001-Fix-REPACK-decoding-worker-not-cleaned-up-on-FATAL-e.patch
Description: Binary data

Reply via email to