mirror of
https://github.com/postgres/postgres.git
synced 2025-08-14 02:22:38 +03:00
Perform a lot more sanity checks when freezing tuples.
The previous commit has shown that the sanity checks around freezing aren't strong enough. Strengthening them seems especially important because the existance of the bug has caused corruption that we don't want to make even worse during future vacuum cycles. The errors are emitted with ereport rather than elog, despite being "should never happen" messages, so a proper error code is emitted. To avoid superflous translations, mark messages as internal. Author: Andres Freund and Alvaro Herrera Reviewed-By: Alvaro Herrera, Michael Paquier Discussion: https://postgr.es/m/20171102112019.33wb7g5wp4zpjelu@alap3.anarazel.de Backpatch: 9.3-
This commit is contained in:
@@ -467,6 +467,8 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats,
|
||||
blkno;
|
||||
HeapTupleData tuple;
|
||||
char *relname;
|
||||
TransactionId relfrozenxid = onerel->rd_rel->relfrozenxid;
|
||||
TransactionId relminmxid = onerel->rd_rel->relminmxid;
|
||||
BlockNumber empty_pages,
|
||||
vacuumed_pages;
|
||||
double num_tuples,
|
||||
@@ -1004,6 +1006,13 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats,
|
||||
* tuple, we choose to keep it, because it'll be a lot
|
||||
* cheaper to get rid of it in the next pruning pass than
|
||||
* to treat it like an indexed tuple.
|
||||
*
|
||||
* If this were to happen for a tuple that actually needed
|
||||
* to be deleted, we'd be in trouble, because it'd
|
||||
* possibly leave a tuple below the relation's xmin
|
||||
* horizon alive. heap_prepare_freeze_tuple() is prepared
|
||||
* to detect that case and abort the transaction,
|
||||
* preventing corruption.
|
||||
*/
|
||||
if (HeapTupleIsHotUpdated(&tuple) ||
|
||||
HeapTupleIsHeapOnly(&tuple))
|
||||
@@ -1095,8 +1104,10 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats,
|
||||
* Each non-removable tuple must be checked to see if it needs
|
||||
* freezing. Note we already have exclusive buffer lock.
|
||||
*/
|
||||
if (heap_prepare_freeze_tuple(tuple.t_data, FreezeLimit,
|
||||
MultiXactCutoff, &frozen[nfrozen],
|
||||
if (heap_prepare_freeze_tuple(tuple.t_data,
|
||||
relfrozenxid, relminmxid,
|
||||
FreezeLimit, MultiXactCutoff,
|
||||
&frozen[nfrozen],
|
||||
&tuple_totally_frozen))
|
||||
frozen[nfrozen++].offset = offnum;
|
||||
|
||||
|
Reference in New Issue
Block a user