Skip to content

Commit 917c1c4

Browse files
author
Alexander Korotkov
committed
Fix work with epoch when update moves tuples from one page to another.
1 parent 777476c commit 917c1c4

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

src/backend/access/heap/heapam.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3890,7 +3890,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
38903890
HeapTuple heaptup;
38913891
HeapTuple old_key_tuple = NULL;
38923892
bool old_key_copied = false;
3893-
Page page;
3893+
Page page,
3894+
newpage;
38943895
BlockNumber block;
38953896
MultiXactStatus mxact_status;
38963897
Buffer buffer,
@@ -4120,6 +4121,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
41204121
checked_lockers = true;
41214122
locker_remains = remain != 0;
41224123
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
4124+
HeapTupleCopyEpochFromPage(&oldtup, page);
41234125

41244126
/*
41254127
* If xwait had just locked the tuple then some other xact
@@ -4201,6 +4203,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
42014203
checked_lockers = true;
42024204
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
42034205

4206+
HeapTupleCopyEpochFromPage(&oldtup, page);
4207+
42044208
/*
42054209
* xwait is done, but if xwait had just locked the tuple then some
42064210
* other xact could update this tuple before we get to this point.
@@ -4264,6 +4268,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
42644268
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
42654269
visibilitymap_pin(relation, block, &vmbuffer);
42664270
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
4271+
HeapTupleCopyEpochFromPage(&oldtup, page);
42674272
goto l2;
42684273
}
42694274

@@ -4325,14 +4330,13 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
43254330
*/
43264331
newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
43274332
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-
43334333
HeapTupleHeaderSetCmin(newtup->t_data, cid);
43344334
newtup->t_data->t_infomask |= HEAP_UPDATED | infomask_new_tuple;
43354335
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);
43364340
heap_page_prepare_for_xid(relation, buffer, xmax_new_tuple,
43374341
(newtup->t_data->t_infomask & HEAP_XMAX_IS_MULTI) ? true : false);
43384342
HeapTupleCopyEpochFromPage(newtup, page);
@@ -4619,6 +4623,20 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
46194623
HeapTupleClearHeapOnly(newtup);
46204624
}
46214625

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+
46224640
RelationPutHeapTuple(relation, newbuf, heaptup, false, xid); /* insert new tuple */
46234641

46244642
/* Clear obsolete visibility flags, possibly set by ourselves above... */

0 commit comments

Comments
 (0)