Re: Implement waiting for wal lsn replay: reloaded

Xuneng Zhou <xunengzhou@gmail.com>

From: Xuneng Zhou <xunengzhou@gmail.com>
To: Alexander Korotkov <aekorotkov@gmail.com>
Cc: Álvaro Herrera <alvherre@kurilemu.de>, Chao Li <li.evan.chao@gmail.com>, pgsql-hackers <pgsql-hackers@lists.postgresql.org>, Andres Freund <andres@anarazel.de>, Michael Paquier <michael@paquier.xyz>, jian he <jian.universality@gmail.com>, Tomas Vondra <tomas@vondra.me>, Yura Sokolov <y.sokolov@postgrespro.ru>
Date: 2026-01-03T16:10:44Z
Lists: pgsql-hackers
Hi Alexander,

On Sat, Jan 3, 2026 at 6:54 AM Alexander Korotkov <aekorotkov@gmail.com> wrote:
>
> Hi, Xuneng!
>
> On Fri, Jan 2, 2026 at 11:17 AM Xuneng Zhou <xunengzhou@gmail.com> wrote:
> > On Fri, Jan 2, 2026 at 7:42 AM Alexander Korotkov <aekorotkov@gmail.com> wrote:
> > >
> > > On Thu, Jan 1, 2026 at 7:16 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
> > > > In 0002 you have this kind of thing:
> > > >
> > > > >                               ereport(ERROR,
> > > > >                                               errcode(ERRCODE_QUERY_CANCELED),
> > > > > -                                             errmsg("timed out while waiting for target LSN %X/%08X to be replayed; current replay LSN %X/%08X",
> > > > > +                                             errmsg("timed out while waiting for target LSN %X/%08X to be %s; current %s LSN %X/%08X",
> > > > >                                                          LSN_FORMAT_ARGS(lsn),
> > > > > -                                                        LSN_FORMAT_ARGS(GetXLogReplayRecPtr(NULL))));
> > > > > +                                                        desc->verb,
> > > > > +                                                        desc->noun,
> > > > > +                                                        LSN_FORMAT_ARGS(currentLSN)));
> > > > > +                     }
> > > >
> > > >
> > > > I'm afraid this technique doesn't work, for translatability reasons.
> > > > Your whole design of having a struct with ->verb and ->noun is not
> > > > workable (which is a pity, but you can't really fight this.) You need to
> > > > spell out the whole messages for each case, something like
> > > >
> > > > if (lsntype == replay)
> > > >    ereport(ERROR,
> > > >            errcode(ERRCODE_QUERY_CANCELED),
> > > >            errmsg("timed out while waiting for target LSN %X/%08X to be replayed; current standby_replay LSN %X/%08X",
> > > > else if (lsntype == flush)
> > > >     ereport( ... )
> > > >
> > > > and so on.  This means four separate messages for translation for each
> > > > message your patch is adding, which is IMO the correct approach.
> > >
> > > +1
> > > Thank you for catching this, Alvaro.  Yes, I think we need to get rid
> > > of WaitLSNTypeDesc.  It's nice idea, but we support too many languages
> > > to have something like this.
> > >
> >
> > Thanks for pointing this out. This approach doesn’t scale to multiple
> > languages. While switch statements are more verbose, the extra clarity
> > is justified to preserve proper internationalization. Please check the
> > updated v12.
>
> I've corrected the patchset.  Mostly changed just comments, formatting
> etc.  I'm going to push it if no objections.
>

Thanks for updating the patchset. LGTM.

-- 
Best,
Xuneng



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Clean up 019_replslot_limit.pl comments

  2. Stabilize 019_replslot_limit.pl: wait on slot restart_lsn

  3. Fix memory ordering in WAIT FOR LSN wakeup mechanism

  4. Improve WAIT FOR LSN test coverage

  5. Remove redundant WAIT FOR LSN caller-side pre-checks

  6. Use barrier semantics when reading/writing writtenUpto

  7. Use replay position as floor for WAIT FOR LSN standby_(write|flush)

  8. Wake standby_write/standby_flush waiters from the WAL replay loop

  9. Minimal fix for WAIT FOR ... MODE 'standby_flush'

  10. Avoid syscache lookup while building a WAIT FOR tuple descriptor

  11. Document that WAIT FOR may be interrupted by recovery conflicts

  12. Use WAIT FOR LSN in PostgreSQL::Test::Cluster::wait_for_catchup()

  13. Wake LSN waiters before recovery target stop

  14. Remove redundant pg_unreachable() after elog(ERROR) from ExecWaitStmt()

  15. Revert "Use WAIT FOR LSN in PostgreSQL::Test::Cluster::wait_for_catchup()"

  16. Fix variable usage in wakeupWaiters()

  17. Add tab completion for the WAIT FOR LSN MODE option

  18. Add the MODE option to the WAIT FOR LSN command

  19. Extend xlogwait infrastructure with write and flush wait types

  20. Unify error messages

  21. Optimize shared memory usage for WaitLSNProcInfo

  22. Fix WaitLSNWakeup() fast-path check for InvalidXLogRecPtr

  23. Fix incorrect function name in comments

  24. Add infrastructure for efficient LSN waiting

  25. Add pairingheap_initialize() for shared memory usage

  26. Implement WAIT FOR command