Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9954e1f

Browse files
committed
In WAL replay, restore GIN metapage unconditionally to avoid torn page.
We don't take a full-page image of the GIN metapage; instead, the WAL recordcontains all the information required to reconstruct it from scratch. Butto avoid torn page hazards, we must re-initialize it from the WAL recordevery time, even if it already has a greater LSN, similar to how normal fullpage images are restored.This was highly unlikely to cause any problems in practice, because the GINmetapage is small. We rely on an update smaller than a 512 byte disk sectorto be atomic elsewhere, at least in pg_control. But better safe than sorry,and this would be easy to overlook if more fields are added to the metapageso that it's no longer small.Reported by Noah Misch. Backpatch to all supported versions.
1 parent0f714c6 commit9954e1f

File tree

1 file changed

+13
-14
lines changed

1 file changed

+13
-14
lines changed

‎src/backend/access/gin/ginxlog.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -513,18 +513,20 @@ ginRedoUpdateMetapage(XLogRecPtr lsn, XLogRecord *record)
513513
Pagemetapage;
514514
Bufferbuffer;
515515

516+
/*
517+
* Restore the metapage. This is essentially the same as a full-page image,
518+
* so restore the metapage unconditionally without looking at the LSN, to
519+
* avoid torn page hazards.
520+
*/
516521
metabuffer=XLogReadBuffer(data->node,GIN_METAPAGE_BLKNO, false);
517522
if (!BufferIsValid(metabuffer))
518523
return;/* assume index was deleted, nothing to do */
519524
metapage=BufferGetPage(metabuffer);
520525

521-
if (!XLByteLE(lsn,PageGetLSN(metapage)))
522-
{
523-
memcpy(GinPageGetMeta(metapage),&data->metadata,sizeof(GinMetaPageData));
524-
PageSetLSN(metapage,lsn);
525-
PageSetTLI(metapage,ThisTimeLineID);
526-
MarkBufferDirty(metabuffer);
527-
}
526+
memcpy(GinPageGetMeta(metapage),&data->metadata,sizeof(GinMetaPageData));
527+
PageSetLSN(metapage,lsn);
528+
PageSetTLI(metapage,ThisTimeLineID);
529+
MarkBufferDirty(metabuffer);
528530

529531
if (data->ntuples>0)
530532
{
@@ -677,13 +679,10 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
677679
return;/* assume index was deleted, nothing to do */
678680
metapage=BufferGetPage(metabuffer);
679681

680-
if (!XLByteLE(lsn,PageGetLSN(metapage)))
681-
{
682-
memcpy(GinPageGetMeta(metapage),&data->metadata,sizeof(GinMetaPageData));
683-
PageSetLSN(metapage,lsn);
684-
PageSetTLI(metapage,ThisTimeLineID);
685-
MarkBufferDirty(metabuffer);
686-
}
682+
memcpy(GinPageGetMeta(metapage),&data->metadata,sizeof(GinMetaPageData));
683+
PageSetLSN(metapage,lsn);
684+
PageSetTLI(metapage,ThisTimeLineID);
685+
MarkBufferDirty(metabuffer);
687686

688687
/*
689688
* In normal operation, shiftList() takes exclusive lock on all the

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp