Skip to content

Commit 686a719

Browse files
committed
Protect against torn pages when deleting GIN list pages.
To-be-deleted list pages contain no useful information, as they are being deleted, but we must still protect the writes from being torn by a crash after a partial write. To do that, re-initialize the pages on WAL replay. Jeff Janes caught this with a test program to test partial writes. Backpatch to all supported versions.
1 parent 5c5bfc0 commit 686a719

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

src/backend/access/gin/ginxlog.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -699,26 +699,26 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
699699
* cannot get past a reader that is on, or due to visit, any page we are
700700
* going to delete. New incoming readers will block behind our metapage
701701
* lock and then see a fully updated page list.
702+
*
703+
* No full-page images are taken of the deleted pages. Instead, they are
704+
* re-initialized as empty, deleted pages. Their right-links don't need to
705+
* be preserved, because no new readers can see the pages, as explained
706+
* above.
702707
*/
703708
for (i = 0; i < data->ndeleted; i++)
704709
{
705-
Buffer buffer = XLogReadBuffer(data->node, data->toDelete[i], false);
710+
Buffer buffer;
711+
Page page;
706712

707-
if (BufferIsValid(buffer))
708-
{
709-
Page page = BufferGetPage(buffer);
710-
711-
if (!XLByteLE(lsn, PageGetLSN(page)))
712-
{
713-
GinPageGetOpaque(page)->flags = GIN_DELETED;
713+
buffer = XLogReadBuffer(data->node, data->toDelete[i], true);
714+
page = BufferGetPage(buffer);
715+
GinInitBuffer(buffer, GIN_DELETED);
714716

715-
PageSetLSN(page, lsn);
716-
PageSetTLI(page, ThisTimeLineID);
717-
MarkBufferDirty(buffer);
718-
}
717+
PageSetLSN(page, lsn);
718+
PageSetTLI(page, ThisTimeLineID);
719+
MarkBufferDirty(buffer);
719720

720-
UnlockReleaseBuffer(buffer);
721-
}
721+
UnlockReleaseBuffer(buffer);
722722
}
723723
UnlockReleaseBuffer(metabuffer);
724724
}

0 commit comments

Comments
 (0)