| From: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
|---|---|
| To: | Melanie Plageman <melanieplageman(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Andres Freund <andres(at)anarazel(dot)de> |
| Subject: | Re: All-visible pages with valid prune xid are confusing |
| Date: | 2025-12-02 17:49:05 |
| Message-ID: | 269becdc-a51b-473d-bd40-96ee9f0e2a5d@iki.fi |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On 02/12/2025 18:20, Melanie Plageman wrote:
> Hi,
>
> We currently do not set pd_prune_xid (the oldest prunable XID) when
> replaying XLOG_HEAP2_PRUNE* records. We've never done this, AFAICT.
>
> Since 8.3, this comment has been in the pruning redo function:
>
> * Note: we don't worry about updating the page's prunability hints.
> * At worst this will cause an extra prune cycle to occur soon.
>
> During normal operation, when a page has no prunable tuples, we set
> pd_prune_xid to InvalidTransactionId. But during recovery, the old
> value is left behind.
>
> When we then set the page all-visible in the VM, the page is marked
> all-visible but the prune hint claims there are prunable tuples. On
> the standby, this triggers an unnecessary prune cycle of almost all
> all-visible pages the next time they are accessed. However, I think
> the page being in this confusing state is the bigger problem. It's not
> incorrect, but it seems like it could mask actual page corruption
> (e.g. when there are dead tuples and we mistakenly set the page
> all-visible).
>
> Fixing this would require adding the prune xid to the WAL record.
> UPDATE/DELETE WAL records don't have to include the new prune xid
> because they set the page prune hint to the xlog record's transaction
> ID.
>
> If we don't think the overhead of the extra transaction ID in the WAL
> record is worth it, we could set the prune hint to
> InvalidTranasctionId during recovery if the page is all-visible. This
> would at least avoid that confusing page state.
Hmm. If the page has no prunable tuples left, it makes sense to set
pd_prune_xid to InvalidTransactionId to avoid the useless round of
pruning. In other cases, it would make sense to set it to some XID so
that it gets pruned later. But a standby will only start pruning if it's
later promoted to become a primary. At that point, all currently running
transactions will be finished (except for prepared transactions).
Therefore it doesn't seem important what we set the prune XID to. Any
valid XID that's not in the future should do the trick. So how about
adding a boolean flag to the WAL record, to indicate whether there's
anything prunable left on the page or not?
- Heikki
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Peter Geoghegan | 2025-12-02 17:59:19 | Re: Bug in amcheck? |
| Previous Message | Nathan Bossart | 2025-12-02 17:17:39 | use LW_SHARED in dsa_get_total_size() |