From: | Melanie Plageman <melanieplageman(at)gmail(dot)com> |
---|---|
To: | Peter Geoghegan <pg(at)bowt(dot)ie> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
Subject: | Re: Correcting freeze conflict horizon calculation |
Date: | 2025-05-30 21:56:50 |
Message-ID: | CAAKRu_aXXTHt-xMMa5KApB-LN5vV6+X4OGQrpC-aiBOPP5MjYA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Fri, May 30, 2025 at 5:34 PM Peter Geoghegan <pg(at)bowt(dot)ie> wrote:
>
> On Fri, May 30, 2025 at 5:16 PM Melanie Plageman
> <melanieplageman(at)gmail(dot)com> wrote:
>
> > You're right. I forgot that the visibility_cutoff_xid will be older
> > than OldestXmin when all the tuples are going to be frozen.
>
> I added an assertion in a number of places that
> "Assert(!TransactionIdIsValid(visibility_cutoff_xid))" when we go to
> set a page all-frozen in the VM -- it's irrelvant, and recovery cannot
> possibly need a conflict when it replays the record. This seemed
> logical, since an all-frozen page must already be visible to every
> possible MVCC snapshot (it might also have some small performance
> benefit, though that's not really why I did it).
My point was not about the visibility_cutoff_xid when setting the page
all-frozen in the VM, it was that when you are selecting the snapshot
conflict horizon for the freeze record, if all of the tuples on the
page will be frozen after doing this freezing, then the
visibility_cutoff_xid you calculated while in lazy_scan_prune() will
necessarily be older than OldestXmin -- you only freeze tuples older
than OldestXmin and the visibility_cutoff_xid is the youngest live
tuple's xmin on the page. But since all tuples are older than
OldestXmin, the youngest live tuple's xmin on the page will be older
than OldestXmin (if all of the tuples on the page will be frozen). I
wasn't talking about invalidating the visibility_cutoff_xid for the VM
record at all.
> > I associate the visibility_cutoff_xid with being younger/newer than
> > OldestXmin because it often will be when there are newer live tuples
> > we don't freeze.
>
> I'm not sure what you mean by this. visibility_cutoff_xid can only be
> set using tuples that HTSV says are HEAPTUPLE_LIVE according to
> VACUUM's OldestXmin cutoff. Personally I find it natural to think of
> visibility_cutoff_xid as meaningless unless we're actually able to
> apply it in some way.
Wait, I don't see that.
HeapTupleSatisfiesVacuum() passes OldestXmin which is used to evaluate
if tuples can be seen as dead:
if (TransactionIdPrecedes(dead_after, OldestXmin))
res = HEAPTUPLE_DEAD;
Which doesn't do anything for live tuples.
And HeapTupleSatisfiesVacuumHorizon() returns HEAPTUPLE_LIVE for
tuples whose inserting transaction has committed.
First we check
if (!HeapTupleHeaderXminCommitted(tuple))
then all those cases have returns and then if it was committed we do this:
/*
* Okay, the inserter committed, so it was good at some point. Now what
* about the deleting transaction?
*/
if (tuple->t_infomask & HEAP_XMAX_INVALID)
return HEAPTUPLE_LIVE;
So wouldn't the visibility_cutoff_xid be the newest xmin of a
committed live tuple on the page?
/* Track newest xmin on page. */
if (TransactionIdFollows(xmin,
prunestate->visibility_cutoff_xid) &&
TransactionIdIsNormal(xmin))
prunestate->visibility_cutoff_xid = xmin;
I don't see how OldestXmin comes into play with the visibility_cutoff_xid.
So that was why I thought when there are live committed tuples on the
page that could be newer than OldestXmin, that visibility_cutoff_xid
would be younger than OldestXmin.
- Melanie
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Geoghegan | 2025-05-30 22:10:11 | Re: Correcting freeze conflict horizon calculation |
Previous Message | Peter Geoghegan | 2025-05-30 21:34:27 | Re: Correcting freeze conflict horizon calculation |