Skip to content

Commit 7d80e93

Browse files
committed
Fix data loss on crash after sorted GiST index build.
If a checkpoint happens during the index build, and the system crashes after the checkpoint and the index build have finished, the data written to the index before the checkpoint started could be lost. The checkpoint won't have fsync'd it, and it won't be replayed at crash recovery either. Fix by calling smgrimmedsync() after the index build, just like in B-tree index build. Backpatch to v14 where the sorted GiST index build was introduced. Reported-by: Melanie Plageman Discussion: https://www.postgresql.org/message-id/CAAKRu_ZJJynimxKj5xYBSziL62-iEtPE+fx-B=JzR=jUtP92mw@mail.gmail.com
1 parent dd7c059 commit 7d80e93

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/backend/access/gist/gistbuild.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,21 @@ gist_indexsortbuild(GISTBuildState *state)
461461

462462
pfree(pagestate->page);
463463
pfree(pagestate);
464+
465+
/*
466+
* When we WAL-logged index pages, we must nonetheless fsync index files.
467+
* Since we're building outside shared buffers, a CHECKPOINT occurring
468+
* during the build has no way to flush the previously written data to
469+
* disk (indeed it won't know the index even exists). A crash later on
470+
* would replay WAL from the checkpoint, therefore it wouldn't replay our
471+
* earlier WAL entries. If we do not fsync those pages here, they might
472+
* still not be on disk when the crash occurs.
473+
*/
474+
if (RelationNeedsWAL(state->indexrel))
475+
{
476+
RelationOpenSmgr(state->indexrel);
477+
smgrimmedsync(state->indexrel->rd_smgr, MAIN_FORKNUM);
478+
}
464479
}
465480

466481
/*

0 commit comments

Comments
 (0)