Re: Make mesage at end-of-recovery less scary.

From: Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com>
To: ashu(dot)coek88(at)gmail(dot)com
Cc: pashkin(dot)elfe(at)gmail(dot)com, michael(at)paquier(dot)xyz, bossartn(at)amazon(dot)com, david(at)pgmasters(dot)net, peter(dot)eisentraut(at)2ndquadrant(dot)com, andres(at)anarazel(dot)de, pgsql-hackers(at)lists(dot)postgresql(dot)org, jtc331(at)gmail(dot)com, robertmhaas(at)gmail(dot)com
Subject: Re: Make mesage at end-of-recovery less scary.
Date: 2022-02-09 07:44:14
Message-ID: 20220209.164414.1807834796155134287.horikyota.ntt@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi, Ashutosh.

At Tue, 8 Feb 2022 18:35:34 +0530, Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> wrote in
> Here are some of my review comments on the v11 patch:

Thank you for taking a look on this.

> - (errmsg_internal("reached end of WAL in
> pg_wal, entering archive recovery")));
> + (errmsg_internal("reached end of WAL at %X/%X
> on timeline %u in %s during crash recovery, entering archive
> recovery",
> + LSN_FORMAT_ARGS(ErrRecPtr),
> + replayTLI,
> + xlogSourceNames[currentSource])));
>
> Why crash recovery? Won't this message get printed even during PITR?

It is in the if-block with the following condition.

> * If archive recovery was requested, but we were still doing
> * crash recovery, switch to archive recovery and retry using the
> * offline archive. We have now replayed all the valid WAL in
> * pg_wal, so we are presumably now consistent.
...
> if (!InArchiveRecovery && ArchiveRecoveryRequested)

This means archive-recovery is requested but not started yet. That is,
we've just finished crash recovery. The existing comment cited
together is mentioning that.

At the end of PITR (or archive recovery), the other code works.

> /*
> * If we haven't emit an error message, we have safely reached the
> * end-of-WAL.
> */
> if (emode_for_corrupt_record(LOG, ErrRecPtr) == LOG)
> {
> char *fmt;
>
> if (StandbyMode)
> fmt = gettext_noop("reached end of WAL at %X/%X on timeline %u in %s during standby mode");
> else if (InArchiveRecovery)
> fmt = gettext_noop("reached end of WAL at %X/%X on timeline %u in %s during archive recovery");
> else
> fmt = gettext_noop("reached end of WAL at %X/%X on timeline %u in %s during crash recovery");

The last among the above messages is choosed when archive-recovery is
not requested at all.

> I just did a PITR and could see these messages in the logfile.

Yeah, the log lines are describing that the server starting with crash
recovery to run PITR.

> 2022-02-08 18:00:44.367 IST [86185] LOG: starting point-in-time
> recovery to WAL location (LSN) "0/5227790"
> 2022-02-08 18:00:44.368 IST [86185] LOG: database system was not
> properly shut down; automatic recovery in progress

Well. I guess that the "automatic recovery" is ambiguous. Does it
make sense if the second line were like the follows instead?

+ 2022-02-08 18:00:44.368 IST [86185] LOG: database system was not properly shut down; crash recovery in progress

> 2022-02-08 18:00:44.369 IST [86185] LOG: redo starts at 0/14DC8D8
> 2022-02-08 18:00:44.978 IST [86185] DEBUG1: reached end of WAL at
> 0/3FFFFD0 on timeline 1 in pg_wal during crash recovery, entering
> archive recovery

(I don't include this change in this patch since it would be another
issue.)

> ==
>
> + /*
> + * If we haven't emit an error message, we have safely reached the
> + * end-of-WAL.
> + */
> + if (emode_for_corrupt_record(LOG, ErrRecPtr) == LOG)
> + {
> + char *fmt;
> +
> + if (StandbyMode)
> + fmt = gettext_noop("reached end of WAL at %X/%X on
> timeline %u in %s during standby mode");
> + else if (InArchiveRecovery)
> + fmt = gettext_noop("reached end of WAL at %X/%X on
> timeline %u in %s during archive recovery");
> + else
> + fmt = gettext_noop("reached end of WAL at %X/%X on
> timeline %u in %s during crash recovery");
> +
> + ereport(LOG,
> + (errmsg(fmt, LSN_FORMAT_ARGS(ErrRecPtr), replayTLI,
> + xlogSourceNames[currentSource]),
> + (errormsg ? errdetail_internal("%s", errormsg) : 0)));
> + }
>
> Doesn't it make sense to add an assert statement inside this if-block
> that will check for xlogreader->EndOfWAL?

Good point. On second thought, the condition there is flat wrong.
The message is "reached end of WAL" so the condition should be
EndOfWAL. On the other hand we didn't make sure that the error
message for the stop is emitted anywhere. Thus I don't particularly
want to be strict on that point.

I made the following change for this.

- if (emode_for_corrupt_record(LOG, ErrRecPtr) == LOG)
+ if (xlogreader->EndOfWAL)

> ==
>
> - * We only end up here without a message when XLogPageRead()
> - * failed - in that case we already logged something. In
> - * StandbyMode that only happens if we have been triggered, so we
> - * shouldn't loop anymore in that case.
> + * If we get here for other than end-of-wal, emit the error
> + * message right now. Otherwise the message if any is shown as a
> + * part of the end-of-WAL message below.
> */
>
> For consistency, I think we can replace "end-of-wal" with
> "end-of-WAL". Please note that everywhere else in the comments you
> have used "end-of-WAL". So why not the same here?

Right. Fixed.

> ==
>
> ereport(LOG,
> - (errmsg("replication terminated by
> primary server"),
> - errdetail("End of WAL reached on
> timeline %u at %X/%X.",
> - startpointTLI,
> -
> LSN_FORMAT_ARGS(LogstreamResult.Write))));
> + (errmsg("replication terminated by
> primary server on timeline %u at %X/%X.",
> + startpointTLI,
> +
> LSN_FORMAT_ARGS(LogstreamResult.Write))));
>
> Is this change really required? I don't see any issue with the
> existing error message.

Without the change, we see two similar end-of-WAL messages from both
walreceiver and startup. (Please don't care about the slight
difference of LSNs..)

[walreceiver] LOG: replication terminated by primary server
[walreceiver] DETAIL: End of WAL reached on timeline 1 at 0/B0000D8.
[startup] LOG: reached end of WAL at 0/B000060 on timeline 1 in archive during standby mode
[startup] DETAIL: empty record found at 0/B0000D8

But what the walreceiver detected at the time is not End-of-WAL but an
error on the streaming connection. Since this patch makes startup
process to detect End-of-WAL, we don't need the duplicate and
in-a-sense false end-of-WAL message from walreceiver.

# By the way, I deliberately choosed to report the LSN of last
# successfully record in the "reached end of WAL" message. On second
# thought about this choice, I came to think that it is better to report
# the failure LSN. I changed it to report the failure LSN. In this
# case we face an ambiguity according to how we failed to read the
# record but for now we have no choice than blindly choosing one of
# them. I choosed EndRecPtr since I think decode error happens quite
# rarely than read errors.

[walreceiver] LOG: replication terminated by primary server at 0/B014228 on timeline 1.
[startup] LOG: reached end of WAL at 0/B014228 on timeline 1 in archive during standby mode
[startup] DETAIL: empty record found at 0/B014228

This is the reason for the change.

> Lastly, are we also planning to backport this patch?

This is apparent a behavioral change, not a bug fix, which I think we
regard as not appropriate for back-patching.

As the result, I made the following chages in the version 11.

1. Changed the condition for the "end-of-WAL" message from
emode_for_corrupt_record to the EndOfWAL flag.

2. Corrected the wording of end-of-wal to end-of-WAL.

3. In the "reached end of WAL" message, report the LSN of the
beginning of failed record instead of the beginning of the
last-succeeded record.

4. In the changed message in walreceiver.c, I swapped LSN and timeline
so that they are in the same order with other similar messages.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachment Content-Type Size
v11-0001-Make-End-Of-Recovery-error-less-scary.patch text/x-patch 16.1 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Smith 2022-02-09 07:48:10 Re: row filtering for logical replication
Previous Message Dilip Kumar 2022-02-09 06:18:00 Re: decoupling table and index vacuum