In PostgreSQL, if crashes during VACUUM, will it recover from a checkpoint that is before the frozen transaction ID of VACUUM?
It could well be that the freeze limit is younger than the latest checkpoint, if you set vacuum_freeze_min_age low enough, but that is no problem.
Tuples are either frozen (if they are all-visible and older than vacuum_freeze_min_age transactions) or removed (if they are &quot;dead&quot;: invisible to everyone and no longer needed). Dead tuples are never frozen.
During crash recovery, all actions by VACUUM are replayed (with the possible exception of hint bits), so when recovery is done, all dead tuples are sure to be gone, and all frozen tuples will be frozen again.
Nobody can connect to the database before crash recovery is finished, so there is no danger of anybody seeing inconsistent data.