diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index 76dabf19736cb574a10a8b92ba5542bca875f61f..11b2da163129d998dff59540d40a26cee88afff3 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -720,12 +720,30 @@ ginRedoDeletePage(XLogRecPtr lsn, XLogRecord *record) else { dbuffer = XLogReadBuffer(data->node, data->blkno, false); + + /* + * deleteXid field of ginxlogDeletePage was added during backpatching. + * But, non-backpatched instances will continue generate WAL without + * this field. We should be able to correctly apply that. We can + * distinguish new WAL records by size their data, because + * ginxlogDeletePage changes its size on both 32-bit and 64-bit + * platforms. + */ + StaticAssertStmt(sizeof(ginxlogDeletePage) != + sizeof(ginxlogDeletePageOld), + "ginxlogDeletePage size should be changed " + "with addition of deleteXid field"); + Assert(record->xl_len == sizeof(ginxlogDeletePage) || + record->xl_len == sizeof(ginxlogDeletePageOld)); + if (BufferIsValid(dbuffer)) { page = BufferGetPage(dbuffer); if (lsn > PageGetLSN(page)) { Assert(GinPageIsData(page)); + if (record->xl_len == sizeof(ginxlogDeletePage)) + GinPageSetDeleteXid(page, data->deleteXid); GinPageGetOpaque(page)->flags = GIN_DELETED; PageSetLSN(page, lsn); MarkBufferDirty(dbuffer); diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 6b1ada5d006338b95beff6819cb1ab53a586bf0f..54e55940eb051e3d4dfb891f4573801aa7a53cc6 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -586,6 +586,20 @@ typedef struct ginxlogDeletePage TransactionId deleteXid; /* last Xid which could see this page in scan */ } ginxlogDeletePage; +/* + * Previous version of ginxlogDeletePage struct, which didn't have deleteXid + * field. Used for size comparison (see ginRedoDeletePage()). + */ +typedef struct ginxlogDeletePageOld +{ + RelFileNode node; + BlockNumber blkno; + BlockNumber parentBlkno; + OffsetNumber parentOffset; + BlockNumber leftBlkno; + BlockNumber rightLink; +} ginxlogDeletePageOld; + #define XLOG_GIN_UPDATE_META_PAGE 0x60 typedef struct ginxlogUpdateMeta