Skip to content

Commit 5eb10b5

Browse files
author
Alexander Korotkov
committed
Fix xid of page initialization.
1 parent 5e6641b commit 5eb10b5

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

src/backend/access/heap/heapam.c

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,11 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
25012501
}
25022502

25032503
XLogBeginInsert();
2504+
if (info & XLOG_HEAP_INIT_PAGE)
2505+
{
2506+
PageHeader header = (PageHeader) page;
2507+
XLogRegisterData((char *) &header->pd_xid_epoch, sizeof(TransactionId));
2508+
}
25042509
XLogRegisterData((char *) &xlrec, SizeOfHeapInsert);
25052510

25062511
xlhdr.t_infomask2 = heaptup->t_data->t_infomask2;
@@ -3277,6 +3282,11 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples,
32773282
bufflags |= REGBUF_KEEP_DATA;
32783283

32793284
XLogBeginInsert();
3285+
if (info & XLOG_HEAP_INIT_PAGE)
3286+
{
3287+
PageHeader header = (PageHeader) page;
3288+
XLogRegisterData((char *) &header->pd_xid_epoch, sizeof(TransactionId));
3289+
}
32803290
XLogRegisterData((char *) xlrec, tupledata - scratch);
32813291
XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags);
32823292

@@ -8138,6 +8148,11 @@ log_heap_update(Relation reln, Buffer oldbuf,
81388148
if (oldbuf != newbuf)
81398149
XLogRegisterBuffer(1, oldbuf, REGBUF_STANDARD);
81408150

8151+
if (info & XLOG_HEAP_INIT_PAGE)
8152+
{
8153+
PageHeader header = (PageHeader) page;
8154+
XLogRegisterData((char *) &header->pd_xid_epoch, sizeof(TransactionId));
8155+
}
81418156
XLogRegisterData((char *) &xlrec, SizeOfHeapUpdate);
81428157

81438158
/*
@@ -8795,7 +8810,7 @@ static void
87958810
heap_xlog_insert(XLogReaderState *record)
87968811
{
87978812
XLogRecPtr lsn = record->EndRecPtr;
8798-
xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record);
8813+
xl_heap_insert *xlrec;
87998814
Buffer buffer;
88008815
Page page;
88018816
union
@@ -8811,6 +8826,18 @@ heap_xlog_insert(XLogReaderState *record)
88118826
BlockNumber blkno;
88128827
ItemPointerData target_tid;
88138828
XLogRedoAction action;
8829+
bool isinit = (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
8830+
TransactionId pd_xid_epoch = InvalidTransactionId;
8831+
Pointer rec_data;
8832+
8833+
rec_data = (Pointer) XLogRecGetData(record);
8834+
if (isinit)
8835+
{
8836+
pd_xid_epoch = *((TransactionId *) rec_data);
8837+
rec_data += sizeof(TransactionId);
8838+
}
8839+
8840+
xlrec = (xl_heap_insert *) rec_data;
88148841

88158842
XLogRecGetBlockTag(record, 0, &target_node, NULL, &blkno);
88168843
ItemPointerSetBlockNumber(&target_tid, blkno);
@@ -8835,11 +8862,15 @@ heap_xlog_insert(XLogReaderState *record)
88358862
* If we inserted the first and only tuple on the page, re-initialize the
88368863
* page from scratch.
88378864
*/
8838-
if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE)
8865+
if (isinit)
88398866
{
8867+
PageHeader header;
8868+
88408869
buffer = XLogInitBufferForRedo(record, 0);
88418870
page = BufferGetPage(buffer);
88428871
PageInit(page, BufferGetPageSize(buffer), 0);
8872+
header = (PageHeader) page;
8873+
header->pd_xid_epoch = pd_xid_epoch;
88438874
action = BLK_NEEDS_REDO;
88448875
}
88458876
else
@@ -8927,12 +8958,20 @@ heap_xlog_multi_insert(XLogReaderState *record)
89278958
int i;
89288959
bool isinit = (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
89298960
XLogRedoAction action;
8961+
TransactionId pd_xid_epoch = InvalidTransactionId;
8962+
Pointer rec_data;
89308963

89318964
/*
89328965
* Insertion doesn't overwrite MVCC data, so no conflict processing is
89338966
* required.
89348967
*/
8935-
xlrec = (xl_heap_multi_insert *) XLogRecGetData(record);
8968+
rec_data = (Pointer) XLogRecGetData(record);
8969+
if (isinit)
8970+
{
8971+
pd_xid_epoch = *((TransactionId *) rec_data);
8972+
rec_data += sizeof(TransactionId);
8973+
}
8974+
xlrec = (xl_heap_multi_insert *) rec_data;
89368975

89378976
XLogRecGetBlockTag(record, 0, &rnode, NULL, &blkno);
89388977

@@ -8953,9 +8992,13 @@ heap_xlog_multi_insert(XLogReaderState *record)
89538992

89548993
if (isinit)
89558994
{
8995+
PageHeader header;
8996+
89568997
buffer = XLogInitBufferForRedo(record, 0);
89578998
page = BufferGetPage(buffer);
89588999
PageInit(page, BufferGetPageSize(buffer), 0);
9000+
header = (PageHeader) page;
9001+
header->pd_xid_epoch = pd_xid_epoch;
89599002
action = BLK_NEEDS_REDO;
89609003
}
89619004
else
@@ -9050,7 +9093,7 @@ static void
90509093
heap_xlog_update(XLogReaderState *record, bool hot_update)
90519094
{
90529095
XLogRecPtr lsn = record->EndRecPtr;
9053-
xl_heap_update *xlrec = (xl_heap_update *) XLogRecGetData(record);
9096+
xl_heap_update *xlrec;
90549097
RelFileNode rnode;
90559098
BlockNumber oldblk;
90569099
BlockNumber newblk;
@@ -9075,6 +9118,18 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
90759118
Size freespace = 0;
90769119
XLogRedoAction oldaction;
90779120
XLogRedoAction newaction;
9121+
bool isinit = (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
9122+
TransactionId pd_xid_epoch = InvalidTransactionId;
9123+
Pointer rec_data;
9124+
9125+
rec_data = (Pointer *) XLogRecGetData(record);
9126+
if (isinit)
9127+
{
9128+
pd_xid_epoch = *((TransactionId *) rec_data);
9129+
rec_data += sizeof(TransactionId);
9130+
}
9131+
9132+
xlrec = (xl_heap_update *) rec_data;
90789133

90799134
/* initialize to keep the compiler quiet */
90809135
oldtup.t_data = NULL;
@@ -9166,11 +9221,15 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
91669221
nbuffer = obuffer;
91679222
newaction = oldaction;
91689223
}
9169-
else if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE)
9224+
else if (isinit)
91709225
{
9226+
PageHeader header;
9227+
91719228
nbuffer = XLogInitBufferForRedo(record, 0);
91729229
page = (Page) BufferGetPage(nbuffer);
91739230
PageInit(page, BufferGetPageSize(nbuffer), 0);
9231+
header = (PageHeader) page;
9232+
header->pd_xid_epoch = pd_xid_epoch;
91749233
newaction = BLK_NEEDS_REDO;
91759234
}
91769235
else

src/backend/access/transam/xlog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4806,7 +4806,7 @@ BootStrapXLOG(void)
48064806
checkPoint.ThisTimeLineID = ThisTimeLineID;
48074807
checkPoint.PrevTimeLineID = ThisTimeLineID;
48084808
checkPoint.fullPageWrites = fullPageWrites;
4809-
checkPoint.nextXid = FirstNormalTransactionId + 1;
4809+
checkPoint.nextXid = FirstNormalTransactionId + 1 + 0x4000000000000000;
48104810
checkPoint.nextOid = FirstBootstrapObjectId;
48114811
checkPoint.nextMulti = FirstMultiXactId;
48124812
checkPoint.nextMultiOffset = 0;

src/backend/replication/logical/decode.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,13 @@ DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
646646
xl_heap_insert *xlrec;
647647
ReorderBufferChange *change;
648648
RelFileNode target_node;
649+
bool isinit = (XLogRecGetInfo(r) & XLOG_HEAP_INIT_PAGE) != 0;
650+
Pointer rec_data;
649651

650-
xlrec = (xl_heap_insert *) XLogRecGetData(r);
652+
rec_data = (Pointer) XLogRecGetData(r);
653+
if (isinit)
654+
rec_data += sizeof(TransactionId);
655+
xlrec = (xl_heap_insert *) rec_data;
651656

652657
/* only interested in our database */
653658
XLogRecGetBlockTag(r, 0, &target_node, NULL, NULL);
@@ -698,8 +703,13 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
698703
ReorderBufferChange *change;
699704
char *data;
700705
RelFileNode target_node;
706+
bool isinit = (XLogRecGetInfo(r) & XLOG_HEAP_INIT_PAGE) != 0;
707+
Pointer rec_data;
701708

702-
xlrec = (xl_heap_update *) XLogRecGetData(r);
709+
rec_data = (Pointer) XLogRecGetData(r);
710+
if (isinit)
711+
rec_data += sizeof(TransactionId);
712+
xlrec = (xl_heap_update *) rec_data;
703713

704714
/* only interested in our database */
705715
XLogRecGetBlockTag(r, 0, &target_node, NULL, NULL);
@@ -823,8 +833,13 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
823833
char *tupledata;
824834
Size tuplelen;
825835
RelFileNode rnode;
836+
bool isinit = (XLogRecGetInfo(r) & XLOG_HEAP_INIT_PAGE) != 0;
837+
Pointer rec_data;
826838

827-
xlrec = (xl_heap_multi_insert *) XLogRecGetData(r);
839+
rec_data = (Pointer) XLogRecGetData(r);
840+
if (isinit)
841+
rec_data += sizeof(TransactionId);
842+
xlrec = (xl_heap_multi_insert *) rec_data;
828843

829844
/* only interested in our database */
830845
XLogRecGetBlockTag(r, 0, &rnode, NULL, NULL);

0 commit comments

Comments
 (0)