Hi, heap_abort_speculative() does: /* * The tuple will become DEAD immediately. Flag that this page * immediately is a candidate for pruning by setting xmin to * RecentGlobalXmin. That's not pretty, but it doesn't seem worth * inventing a nicer API for this. */ Assert(TransactionIdIsValid(RecentGlobalXmin)); PageSetPrunable(page, RecentGlobalXmin);
but that doesn't seem right to me. RecentGlobalXmin could very well be older than the table's relfrozenxid. Especially when multiple databases are used, or logical replication is active, it's not unlikely at all. That's because RecentGlobalXmin is a) the minimum xmin of all databases, whereas horizon computations for relations are done for only the current database b) RecentGlobalXmin may have been computed a while ago (when the snapshot for the transaction was computed, for example), but a concurrent vacuum could be more recent c) RecentGlobalXmin includes the more "pessimistic" xmin for catalog relations. Unless somebody has a better idea for how to solve this in a back-paptchable way, I think it'd be best to replace RecentGlobalXmin with RecentXmin. That'd be safe as far as I can see. Greetings, Andres Freund