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

Commit2fa8ba3

Browse files
committed
Fix handling of all-zero pages in SP-GiST vacuum.
SP-GiST initialized an all-zeros page at vacuum, but that was notWAL-logged, which is not safe. You might get a torn page write, when it getsflushed to disk, and end-up with a half-initialized index page. To fix,leave it in the all-zeros state, and add it to the FSM. It will beinitialized when reused. Also don't set the page-deleted flag when recyclingan empty page. That was also not WAL-logged, and a torn write of that wouldcause the page to have an invalid checksum.Backpatch to 9.2, where SP-GiST indexes were added.
1 parent6a0a388 commit2fa8ba3

File tree

2 files changed

+10
-21
lines changed

2 files changed

+10
-21
lines changed

‎src/backend/access/spgist/spgvacuum.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -621,14 +621,10 @@ spgvacuumpage(spgBulkDeleteState *bds, BlockNumber blkno)
621621
{
622622
/*
623623
* We found an all-zero page, which could happen if the database
624-
* crashed just after extending the file.Initialize and recycle it.
624+
* crashed just after extending the file.Recycle it.
625625
*/
626-
SpGistInitBuffer(buffer,0);
627-
SpGistPageSetDeleted(page);
628-
/* We don't bother to WAL-log this action; easy to redo */
629-
MarkBufferDirty(buffer);
630626
}
631-
elseif (SpGistPageIsDeleted(page))
627+
elseif (PageIsEmpty(page))
632628
{
633629
/* nothing to do */
634630
}
@@ -654,30 +650,23 @@ spgvacuumpage(spgBulkDeleteState *bds, BlockNumber blkno)
654650
/*
655651
* The root pages must never be deleted, nor marked as available in FSM,
656652
* because we don't want them ever returned by a search for a place to put
657-
* a new tuple. Otherwise, check for empty/deletable page, and make sure
658-
*FSMknows about it.
653+
* a new tuple. Otherwise, check for empty page, and make sure the FSM
654+
* knows about it.
659655
*/
660656
if (!SpGistBlockIsRoot(blkno))
661657
{
662-
/* If page is now empty, mark it deleted */
663-
if (PageIsEmpty(page)&& !SpGistPageIsDeleted(page))
664-
{
665-
SpGistPageSetDeleted(page);
666-
/* We don't bother to WAL-log this action; easy to redo */
667-
MarkBufferDirty(buffer);
668-
}
669-
670-
if (SpGistPageIsDeleted(page))
658+
if (PageIsEmpty(page))
671659
{
672660
RecordFreeIndexPage(index,blkno);
673661
bds->stats->pages_deleted++;
674662
}
675663
else
664+
{
665+
SpGistSetLastUsedPage(index,buffer);
676666
bds->lastFilledBlock=blkno;
667+
}
677668
}
678669

679-
SpGistSetLastUsedPage(index,buffer);
680-
681670
UnlockReleaseBuffer(buffer);
682671
}
683672

‎src/include/access/spgist_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ typedef SpGistPageOpaqueData *SpGistPageOpaque;
4848

4949
/* Flag bits in page special space */
5050
#defineSPGIST_META(1<<0)
51-
#defineSPGIST_DELETED(1<<1)
51+
#defineSPGIST_DELETED(1<<1)/* never set, but keep for backwards
52+
* compatibility */
5253
#defineSPGIST_LEAF(1<<2)
5354
#defineSPGIST_NULLS(1<<3)
5455

5556
#defineSpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page))
5657
#defineSpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META)
5758
#defineSpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED)
58-
#defineSpGistPageSetDeleted(page) (SpGistPageGetOpaque(page)->flags |= SPGIST_DELETED)
5959
#defineSpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF)
6060
#defineSpGistPageStoresNulls(page) (SpGistPageGetOpaque(page)->flags & SPGIST_NULLS)
6161

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp