Re: BUG #17257: (auto)vacuum hangs within lazy_scan_prune()
Peter Geoghegan <pg@bowt.ie>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Ensure vacuum removes all visibly dead tuples older than OldestXmin
- 06bf404cd07b 16.4 landed
- 45ce054c02b8 14.13 landed
- dc6354c67017 15.8 landed
-
Combine freezing and pruning steps in VACUUM
- 6dbb490261a6 17.0 cited
-
Handle non-chain tuples outside of heap_prune_chain()
- 6f47f6883151 17.0 cited
-
Fix false reports in pg_visibility
- e85662df44ff 17.0 cited
-
Remove retry loop in heap_page_prune().
- 1ccc1e05ae8f 17.0 cited
-
vacuumlazy.c: document vistest and OldestXmin.
- 73f6ec3d3c8d 15.0 cited
-
Deduplicate choice of horizon for a relation procarray.c.
- d9d8aa9bb9aa 15.0 cited
-
Remove tupgone special case from vacuumlazy.c.
- 8523492d4e34 14.0 cited
-
Simplify state managed by VACUUM.
- b4af70cb2103 14.0 cited
-
Recycle nbtree pages deleted during same VACUUM.
- 9dd963ae2534 14.0 cited
-
snapshot scalability: Don't compute global horizons while building snapshots.
- dc7420c2c927 14.0 cited
-
Raise error when affecting tuple moved into different partition.
- f16241bef7cc 11.0 cited
On Sat, Apr 27, 2024 at 10:38 AM Melanie Plageman <melanieplageman@gmail.com> wrote: > In 17, we don't ever get a new HTSV_Result, so if the tuple is not > removed, it would be because HeapTupleSatisfiesVacuumHorizon() > returned HEAPTUPLE_RECENTLY_DEAD and, if GlobalVisTestIsRemovableXid() > was called, dead_after did not precede GlobalVisState->maybe_needed. > This tuple, during this vacuum of the relation, would never be > determined to be HEAPTUPLE_DEAD or it would have been removed. That makes sense. > > > It will always be HEAPTUPLE_RECENTLY_DEAD in 17 and in <= 16, if > > > HeapTupleSatisfiesVacuum() returns HEAPTUPLE_DEAD, we wouldn't call > > > heap_prepare_freeze_tuple() because of the retry loop. > > > > The retry loop exists precisely because heap_prepare_freeze_tuple() > > isn't prepared to deal with HEAPTUPLE_DEAD tuples. So I agree that > > that won't be allowed to happen on versions that have the retry loop > > (14 - 16). > > So, it can't happen in back branches. Let's just address 17. Help me > understand how this can happen in 17. Just to be clear, I never said that it was possible in 17. If I somehow implied it, then I didn't mean to. > > As Andres pointed out, even if we were to call > > heap_prepare_freeze_tuple() with a HEAPTUPLE_DEAD tuple, we'd get a > > "can't happen" error (though it's hard to see this because it doesn't > > actually rely on the hint bits set in the tuple). > > I just don't see how in 17 we could end up calling > heap_prepare_freeze_tuple() on a HEAPTUPLE_DEAD tuple. If > heap_prune_satisfies_vacuum() returned HEAPTUPLE_DEAD, we wouldn't > heap_prepare_freeze_tuple() the tuple. That part seems relatively straightforward. > I assume you are talking about a HEAPTUPLE_RECENTLY_DEAD tuple that > *should* be HEAPTUPLE_DEAD. But it doesn't really matter if it should > be HEAPTUPLE_DEAD and we fail to remove it, as long as we don't leave > it unfrozen and advance relfrozenxid past its xids. I'm not sure that I agree with this part. You're describing a scheme under which aggressive VACUUM isn't strictly guaranteed to respect FreezeLimit. And so (for example) a VACUUM FREEZE wouldn't advance relfrozenxid right up to OldestXmin/FreezeLimit. Right? It certainly seems possible that, all things considered, you're right -- perhaps it literally doesn't matter at all on 17, at least in practice. I cannot think of any problem that's worse than an assertion failure within heap_vacuum_rel, just before we go to advance the rel's pg_class.relfrozenxid (and even that seems extremely unlikely). Nobody particularly intended for things to work this way (the FreezeLimit invariant isn't supposed to be violated), but it'd hardly be the first time that something like this happened. Far from it. -- Peter Geoghegan