Skip to content

Commit 6c46e8a

Browse files
committed
Fix data loss on crash after sorted GiST index build.
If a checkpoint happens during sorted GiST index build, and the system crashes after the checkpoint and after the index build has finished, the data written to the index before the checkpoint started could be lost. The checkpoint won't fsync 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 e77216f commit 6c46e8a

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

src/backend/access/gist/gistbuild.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,18 @@ gist_indexsortbuild(GISTBuildState *state)
467467

468468
pfree(levelstate->pages[0]);
469469
pfree(levelstate);
470+
471+
/*
472+
* When we WAL-logged index pages, we must nonetheless fsync index files.
473+
* Since we're building outside shared buffers, a CHECKPOINT occurring
474+
* during the build has no way to flush the previously written data to
475+
* disk (indeed it won't know the index even exists). A crash later on
476+
* would replay WAL from the checkpoint, therefore it wouldn't replay our
477+
* earlier WAL entries. If we do not fsync those pages here, they might
478+
* still not be on disk when the crash occurs.
479+
*/
480+
if (RelationNeedsWAL(state->indexrel))
481+
smgrimmedsync(RelationGetSmgr(state->indexrel), MAIN_FORKNUM);
470482
}
471483

472484
/*

0 commit comments

Comments
 (0)