Re: Incorrect assumption in heap_prepare_freeze_tuple

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Kuntal Ghosh <kuntalghosh.2007@gmail.com>
Cc: PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2020-10-03T19:03:05Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix some problems with VACUUM (INDEX_CLEANUP FALSE).

Hi,

On 2020-10-03 19:57:03 +0530, Kuntal Ghosh wrote:
> You've also mentioned that HEAPTUPLE_DEAD case I'm referring to can
> only be hit for for tuples that are *newer* than OldestXmin but become
> DEAD (instead of RECENTLY_DEAD) because the inserting transaction
> aborted. But, I don't see that's the only case when
> HeapTupleSatisfiesVacuum returns HEAPTUPLE_DEAD. If
> HeapTupleSatisfiesVacuumHorizon returns HEAPTUPLE_RECENTLY_DEAD and if
> tuple xmax(dead_after) precedes OlestXmin, we set it as
> HEAPTUPLE_DEAD.
> 
>     res = HeapTupleSatisfiesVacuumHorizon(htup, buffer, &dead_after);
> 
>     if (res == HEAPTUPLE_RECENTLY_DEAD)
>     {
>         Assert(TransactionIdIsValid(dead_after));
> 
>         if (TransactionIdPrecedes(dead_after, OldestXmin))
>             res = HEAPTUPLE_DEAD;
>     }
>     else
>         Assert(!TransactionIdIsValid(dead_after));
> 
> Am I missing something here?

To get to this point heap_page_prune() has to have been called for the
page. That removes all tuple [versions] that are DEAD. But not
RECENTLY_DEAD. But RECENTLY_DEAD can only happen for tuples that are
newere than OldestXmin. Thus the only tuples that the HTSV() we're
talking about can return DEAD for are ones that were RECENTLY_DEAD
in heap_page_prune().

Greetings,

Andres Freund