Skip to content

Commit 31633f9

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 7603744 commit 31633f9

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
@@ -698,26 +698,26 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
698698
* cannot get past a reader that is on, or due to visit, any page we are
699699
* going to delete. New incoming readers will block behind our metapage
700700
* lock and then see a fully updated page list.
701+
*
702+
* No full-page images are taken of the deleted pages. Instead, they are
703+
* re-initialized as empty, deleted pages. Their right-links don't need to
704+
* be preserved, because no new readers can see the pages, as explained
705+
* above.
701706
*/
702707
for (i = 0; i < data->ndeleted; i++)
703708
{
704-
Buffer buffer = XLogReadBuffer(data->node, data->toDelete[i], false);
709+
Buffer buffer;
710+
Page page;
705711

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

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

719-
UnlockReleaseBuffer(buffer);
720-
}
720+
UnlockReleaseBuffer(buffer);
721721
}
722722
UnlockReleaseBuffer(metabuffer);
723723
}

0 commit comments

Comments
 (0)