| From: | Antonin Houska <ah(at)cybertec(dot)at> |
|---|---|
| To: | Nikolay Samokhvalov <nik(at)postgres(dot)ai> |
| Cc: | Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Nathan Bossart <nathandbossart(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, alvherre(at)kurilemu(dot)de |
| Subject: | Re: REPACK (CONCURRENTLY) backend waits indefinitely when decoding worker fails to start |
| Date: | 2026-09-15 10:26:40 |
| Message-ID: | 26324.1789468000@localhost |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Nikolay Samokhvalov <nik(at)postgres(dot)ai> wrote:
> On Mon, Sep 14, 2026 at 2:00 AM Antonin Houska <ah(at)cybertec(dot)at> wrote:
> > I'm not sure this should be considered a bug. AFAICS the problem happens
> > due to calling proc_exit() directly, i.e. exiting the worker w/o sending a
> > message via the error queue. (If an error was sent,
> > ConditionVariableSleep() should process it and raise ERROR in the backend
> > running REPACK.)
> >
> > However, the REPACK worker does not call proc_exit() directly.
>
> Yes, agreed: the direct proc_exit() test alone didn't establish a bug. I
> checked whether error delivery can actually fail after attachment.
>
> There is a path in mq_putmessage(): an interrupt while blocked on the full
> error queue makes recursive FATAL output detach it via pq_mq_busy. The FATAL
> reaches the server log, but not the REPACK backend.
>
> I reproduced this on v4 plus only the attached repack_worker.c test hooks,
> built with injection points and server-wide client_min_messages=debug1:
>
> 1. For queue_t with a primary key, attach the standard wait action:
>
> create extension injection_points;
> select injection_points_attach(
> 'repack-worker-before-snapshot-export', 'wait');
>
> 2. In another session run repack (concurrently) queue_t. When the worker waits
> at InjectionPoint/repack-worker-before-snapshot-export, SIGSTOP the REPACK
> backend and run:
>
> select injection_points_wakeup(
> 'repack-worker-before-snapshot-export');
>
> 3. Repeat until the worker waits at IPC/MessageQueuePutMessage:
>
> select pg_logical_emit_message(false, 'repack-queue-test',
> repeat('x', 15 * 1024 * 1024));
>
> 4. Run select pg_terminate_backend(worker_pid), wait for the worker to exit,
> then SIGCONT the REPACK backend.
>
I wonder if you forgot to attach some files (I don't see the queue_t table in
the scripts you posted earlier), but I think I was able to reproduce the
problem using the instructions above.
IMO the problem is that the backend ignores the SHM_MQ_DETACHED state in
ProcessRepackMessages(). If all the messages in the queue have severity lower
than ERROR, the worker just processes them and continues waiting for the
worker to export the snapshot. However, as the worker is gone, there's no way
to wake the backend up.
Patch 0002 in [1] should fix that.
Thanks for testing!
--
Antonin Houska
Web: https://www.cybertec-postgresql.com
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Amit Kapila | 2026-09-15 10:35:20 | Re: Distinguish publication exclusions in object addresses |
| Previous Message | Andrei Lepikhov | 2026-09-15 09:59:56 | Re: Do not scan index in right table if condition for left join evaluates to false using columns in left table |