@@ -6377,7 +6377,9 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
6377
6377
* are older than the specified cutoff XID and cutoff MultiXactId. If so,
6378
6378
* setup enough state (in the *frz output argument) to later execute and
6379
6379
* WAL-log what we would need to do, and return TRUE. Return FALSE if nothing
6380
- * is to be changed.
6380
+ * is to be changed. In addition, set *totally_frozen_p to true if the tuple
6381
+ * will be totally frozen after these operations are performed and false if
6382
+ * more freezing will eventually be required.
6381
6383
*
6382
6384
* Caller is responsible for setting the offset field, if appropriate.
6383
6385
*
@@ -6402,12 +6404,12 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
6402
6404
bool
6403
6405
heap_prepare_freeze_tuple (HeapTupleHeader tuple , TransactionId cutoff_xid ,
6404
6406
TransactionId cutoff_multi ,
6405
- xl_heap_freeze_tuple * frz )
6406
-
6407
+ xl_heap_freeze_tuple * frz , bool * totally_frozen_p )
6407
6408
{
6408
6409
bool changed = false;
6409
6410
bool freeze_xmax = false;
6410
6411
TransactionId xid ;
6412
+ bool totally_frozen = true;
6411
6413
6412
6414
frz -> frzflags = 0 ;
6413
6415
frz -> t_infomask2 = tuple -> t_infomask2 ;
@@ -6416,11 +6418,15 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6416
6418
6417
6419
/* Process xmin */
6418
6420
xid = HeapTupleHeaderGetXmin (tuple );
6419
- if (TransactionIdIsNormal (xid ) &&
6420
- TransactionIdPrecedes (xid , cutoff_xid ))
6421
+ if (TransactionIdIsNormal (xid ))
6421
6422
{
6422
- frz -> t_infomask |= HEAP_XMIN_FROZEN ;
6423
- changed = true;
6423
+ if (TransactionIdPrecedes (xid , cutoff_xid ))
6424
+ {
6425
+ frz -> t_infomask |= HEAP_XMIN_FROZEN ;
6426
+ changed = true;
6427
+ }
6428
+ else
6429
+ totally_frozen = false;
6424
6430
}
6425
6431
6426
6432
/*
@@ -6458,6 +6464,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6458
6464
if (flags & FRM_MARK_COMMITTED )
6459
6465
frz -> t_infomask &= HEAP_XMAX_COMMITTED ;
6460
6466
changed = true;
6467
+ totally_frozen = false;
6461
6468
}
6462
6469
else if (flags & FRM_RETURN_IS_MULTI )
6463
6470
{
@@ -6479,16 +6486,19 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6479
6486
frz -> xmax = newxmax ;
6480
6487
6481
6488
changed = true;
6489
+ totally_frozen = false;
6482
6490
}
6483
6491
else
6484
6492
{
6485
6493
Assert (flags & FRM_NOOP );
6486
6494
}
6487
6495
}
6488
- else if (TransactionIdIsNormal (xid ) &&
6489
- TransactionIdPrecedes (xid , cutoff_xid ))
6496
+ else if (TransactionIdIsNormal (xid ))
6490
6497
{
6491
- freeze_xmax = true;
6498
+ if (TransactionIdPrecedes (xid , cutoff_xid ))
6499
+ freeze_xmax = true;
6500
+ else
6501
+ totally_frozen = false;
6492
6502
}
6493
6503
6494
6504
if (freeze_xmax )
@@ -6514,8 +6524,15 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6514
6524
if (tuple -> t_infomask & HEAP_MOVED )
6515
6525
{
6516
6526
xid = HeapTupleHeaderGetXvac (tuple );
6517
- if (TransactionIdIsNormal (xid ) &&
6518
- TransactionIdPrecedes (xid , cutoff_xid ))
6527
+ /*
6528
+ * For Xvac, we ignore the cutoff_xid and just always perform the
6529
+ * freeze operation. The oldest release in which such a value can
6530
+ * actually be set is PostgreSQL 8.4, because old-style VACUUM FULL
6531
+ * was removed in PostgreSQL 9.0. Note that if we were to respect
6532
+ * cutoff_xid here, we'd need to make surely to clear totally_frozen
6533
+ * when we skipped freezing on that basis.
6534
+ */
6535
+ if (TransactionIdIsNormal (xid ))
6519
6536
{
6520
6537
/*
6521
6538
* If a MOVED_OFF tuple is not dead, the xvac transaction must
@@ -6537,6 +6554,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6537
6554
}
6538
6555
}
6539
6556
6557
+ * totally_frozen_p = totally_frozen ;
6540
6558
return changed ;
6541
6559
}
6542
6560
@@ -6587,9 +6605,10 @@ heap_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
6587
6605
{
6588
6606
xl_heap_freeze_tuple frz ;
6589
6607
bool do_freeze ;
6608
+ bool tuple_totally_frozen ;
6590
6609
6591
6610
do_freeze = heap_prepare_freeze_tuple (tuple , cutoff_xid , cutoff_multi ,
6592
- & frz );
6611
+ & frz , & tuple_totally_frozen );
6593
6612
6594
6613
/*
6595
6614
* Note that because this is not a WAL-logged operation, we don't need to
0 commit comments