@@ -3890,7 +3890,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
3890
3890
HeapTuple heaptup ;
3891
3891
HeapTuple old_key_tuple = NULL ;
3892
3892
bool old_key_copied = false;
3893
- Page page ;
3893
+ Page page ,
3894
+ newpage ;
3894
3895
BlockNumber block ;
3895
3896
MultiXactStatus mxact_status ;
3896
3897
Buffer buffer ,
@@ -4120,6 +4121,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
4120
4121
checked_lockers = true;
4121
4122
locker_remains = remain != 0 ;
4122
4123
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
4124
+ HeapTupleCopyEpochFromPage (& oldtup , page );
4123
4125
4124
4126
/*
4125
4127
* If xwait had just locked the tuple then some other xact
@@ -4201,6 +4203,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
4201
4203
checked_lockers = true;
4202
4204
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
4203
4205
4206
+ HeapTupleCopyEpochFromPage (& oldtup , page );
4207
+
4204
4208
/*
4205
4209
* xwait is done, but if xwait had just locked the tuple then some
4206
4210
* other xact could update this tuple before we get to this point.
@@ -4264,6 +4268,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
4264
4268
LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
4265
4269
visibilitymap_pin (relation , block , & vmbuffer );
4266
4270
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
4271
+ HeapTupleCopyEpochFromPage (& oldtup , page );
4267
4272
goto l2 ;
4268
4273
}
4269
4274
@@ -4325,14 +4330,13 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
4325
4330
*/
4326
4331
newtup -> t_data -> t_infomask &= ~(HEAP_XACT_MASK );
4327
4332
newtup -> t_data -> t_infomask2 &= ~(HEAP2_XACT_MASK );
4328
- heap_page_prepare_for_xid (relation , buffer , xid , false);
4329
- HeapTupleCopyEpochFromPage (newtup , page );
4330
- HeapTupleSetXmin (newtup , xid );
4331
-
4332
-
4333
4333
HeapTupleHeaderSetCmin (newtup -> t_data , cid );
4334
4334
newtup -> t_data -> t_infomask |= HEAP_UPDATED | infomask_new_tuple ;
4335
4335
newtup -> t_data -> t_infomask2 |= infomask2_new_tuple ;
4336
+
4337
+ heap_page_prepare_for_xid (relation , buffer , xid , false);
4338
+ HeapTupleCopyEpochFromPage (newtup , page );
4339
+ HeapTupleSetXmin (newtup , xid );
4336
4340
heap_page_prepare_for_xid (relation , buffer , xmax_new_tuple ,
4337
4341
(newtup -> t_data -> t_infomask & HEAP_XMAX_IS_MULTI ) ? true : false);
4338
4342
HeapTupleCopyEpochFromPage (newtup , page );
@@ -4619,6 +4623,20 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
4619
4623
HeapTupleClearHeapOnly (newtup );
4620
4624
}
4621
4625
4626
+ newpage = BufferGetPage (newbuf );
4627
+
4628
+ if (newbuf != buffer )
4629
+ {
4630
+ /* Prepare new page for xids */
4631
+ heap_page_prepare_for_xid (relation , newbuf , xid , false);
4632
+ HeapTupleCopyEpochFromPage (heaptup , newpage );
4633
+ HeapTupleSetXmin (heaptup , xid );
4634
+ heap_page_prepare_for_xid (relation , newbuf , xmax_new_tuple ,
4635
+ (heaptup -> t_data -> t_infomask & HEAP_XMAX_IS_MULTI ) ? true : false);
4636
+ HeapTupleCopyEpochFromPage (heaptup , newpage );
4637
+ HeapTupleSetXmax (heaptup , xmax_new_tuple );
4638
+ }
4639
+
4622
4640
RelationPutHeapTuple (relation , newbuf , heaptup , false, xid ); /* insert new tuple */
4623
4641
4624
4642
/* Clear obsolete visibility flags, possibly set by ourselves above... */
0 commit comments