@@ -2711,6 +2711,15 @@ heap_delete(Relation relation, ItemPointer tid,
2711
2711
2712
2712
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2713
2713
2714
+ lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2715
+ Assert (ItemIdIsNormal (lp ));
2716
+
2717
+ tp .t_tableOid = RelationGetRelid (relation );
2718
+ tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2719
+ tp .t_len = ItemIdGetLength (lp );
2720
+ tp .t_self = * tid ;
2721
+
2722
+ l1 :
2714
2723
/*
2715
2724
* If we didn't pin the visibility map page and the page has become all
2716
2725
* visible while we were busy locking the buffer, we'll have to unlock and
@@ -2724,15 +2733,6 @@ heap_delete(Relation relation, ItemPointer tid,
2724
2733
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2725
2734
}
2726
2735
2727
- lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2728
- Assert (ItemIdIsNormal (lp ));
2729
-
2730
- tp .t_tableOid = RelationGetRelid (relation );
2731
- tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2732
- tp .t_len = ItemIdGetLength (lp );
2733
- tp .t_self = * tid ;
2734
-
2735
- l1 :
2736
2736
result = HeapTupleSatisfiesUpdate (& tp , cid , buffer );
2737
2737
2738
2738
if (result == TM_Invisible )
@@ -2791,8 +2791,12 @@ heap_delete(Relation relation, ItemPointer tid,
2791
2791
* If xwait had just locked the tuple then some other xact
2792
2792
* could update this tuple before we get to this point. Check
2793
2793
* for xmax change, and start over if so.
2794
+ *
2795
+ * We also must start over if we didn't pin the VM page, and
2796
+ * the page has become all visible.
2794
2797
*/
2795
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2798
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2799
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2796
2800
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2797
2801
xwait ))
2798
2802
goto l1 ;
@@ -2824,8 +2828,12 @@ heap_delete(Relation relation, ItemPointer tid,
2824
2828
* xwait is done, but if xwait had just locked the tuple then some
2825
2829
* other xact could update this tuple before we get to this point.
2826
2830
* Check for xmax change, and start over if so.
2831
+ *
2832
+ * We also must start over if we didn't pin the VM page, and the
2833
+ * page has become all visible.
2827
2834
*/
2828
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2835
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2836
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2829
2837
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2830
2838
xwait ))
2831
2839
goto l1 ;
0 commit comments