Re: Adding REPACK [concurrently]

Mihail Nikalayeu <mihailnikalayeu@gmail.com>

From: Mihail Nikalayeu <mihailnikalayeu@gmail.com>
To: Antonin Houska <ah@cybertec.at>
Cc: Andres Freund <andres@anarazel.de>, Amit Kapila <amit.kapila16@gmail.com>, Alvaro Herrera <alvherre@alvh.no-ip.org>, Srinath Reddy Sadipiralla <srinath2133@gmail.com>, Matthias van de Meent <boekewurm+postgres@gmail.com>, Pg Hackers <pgsql-hackers@lists.postgresql.org>, Robert Treat <rob@xzilla.net>
Date: 2026-04-23T11:43:18Z
Lists: pgsql-hackers
Hello!

On Mon, Apr 20, 2026 at 7:44 PM Antonin Houska <ah@cybertec.at> wrote:

> When another process tries to get the lock after that, it checks this field,
> and if it's set, it checks for deadlocks even if deadlock timeout hasn't
> expired yet. If the process is already in the lock's queue and sleeping, the
> lock upgrading process wakes it up so it checks the flag immediately.

In any way there is no sense in waking up other backends just to force
them to cancel themselves.
Better to go in the [0] way - and just cancel another backend if we
are repack and found cycle in the deadlock detector.

We currently have all required infrastructure, even as the comment
described the possibility [1]:

>         * Get this process out of wait state. (Note: we could do this more
>         * efficiently by relying on lockAwaited, but use this coding to
>         * preserve the flexibility to kill some other transaction than the
>         * one detecting the deadlock.)

At the same time version [2] (with FutureWaitLock, explained in more
detail in [3]) is correct and cancels other backends without pointless
waiting, but it feels too complicated due to the complexity of
supporting the FastLock path.

Also, here's one simple idea inspired by your version.
What about adding a new field "do not try to upgrade that lock" to the
LOCK structure? If some backends try to (it has some lockmode and
tries to upgrade it) and it does not has flag 'deadlock_protected'
from [0] - just fail fast with "future deadlock detected".

That way [0] ensures correctness and "do not try to upgrade that lock"
just optimization to fail quickly for the most common scenarios.
Some 2+ backend loops might still wait a long time to be cancelled
(which is solved by [2], but complicated) - but I think this is a
super rare case we can ignore (because repack is still protected from
deadlock).

Mikhail.

[0]: https://www.postgresql.org/message-id/flat/CADzfLwURKVNQ%2B%2BDpi7bjoGfj-8pchDQEVex3eWBx0NCYn6TbDQ%40mail.gmail.com#bceb18354aa20c130a94b1deedd76fb7.
[1]: https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/proc.c#L1870-L1873
[2]: https://www.postgresql.org/message-id/flat/CADzfLwUSnGnkfLwCWHQ%3DVVuAY1YTo%2B0Lr7pb%2BOPWUZbcYKSRUw%40mail.gmail.com#e7ba203b7402de332dfb58ce5329a73a
[3]: https://www.postgresql.org/message-id/flat/CADzfLwVf-3mjMwSTOcj9djNzGd-UjBOYbFjxgXRhtKuH_4rajA%40mail.gmail.com#b69f9c1d1d3d1cbf7f6d66be790894c4



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Allow old WAL recycling during REPACK CONCURRENTLY

  2. Advance restart_lsn more eagerly in LogicalConfirmReceivedLocation

  3. Remove unnecessary signal handler change

  4. Improve REPACK (CONCURRENTLY) error messages some more

  5. Revert "Allow logical replication snapshots to be database-specific"

  6. Move REPACK (CONCURRENTLY) test out of stock regression tests

  7. REPACK: do not require REPLICATION or LOGIN

  8. Add missing initialization

  9. Simplify declaration of memcpy target

  10. Reserve replication slots specifically for REPACK

  11. doc: Add an example of REPACK (CONCURRENTLY)

  12. Allow logical replication snapshots to be database-specific

  13. Avoid different-size pointer-to-integer cast

  14. Fix valgrind failure

  15. Add CONCURRENTLY option to REPACK

  16. Rename cluster.c to repack.c (and corresponding .h)

  17. Allow index_create to suppress index_build progress reporting

  18. Make index_concurrently_create_copy more general

  19. Document the 'command' column of pg_stat_progress_repack

  20. Introduce the REPACK command

  21. Toggle logical decoding dynamically based on logical slot presence.

  22. Split vacuumdb to create vacuuming.c/h

  23. Remove ReorderBufferTupleBuf structure.

  24. Revert changes to CONCURRENTLY that "sped up" Xmin advance

  25. VACUUM: ignore indexing operations with CONCURRENTLY