Sync PG_VERSION file in CREATE DATABASE.
authorNoah Misch <noah@leadboat.com>
Thu, 1 Feb 2024 21:44:19 +0000 (13:44 -0800)
committerNoah Misch <noah@leadboat.com>
Thu, 1 Feb 2024 21:44:22 +0000 (13:44 -0800)
An OS crash could leave PG_VERSION empty or missing.  The same symptom
appeared in a backup by block device snapshot, taken after the next
checkpoint and before the OS flushes the PG_VERSION blocks.  Device
snapshots are not a documented backup method, however.  Back-patch to
v15, where commit 9c08aea6a3090a396be334cc58c511edab05776a introduced
STRATEGY=WAL_LOG and made it the default.

Discussion: https://postgr.es/m/20240130195003.0a.nmisch@google.com

doc/src/sgml/monitoring.sgml
src/backend/commands/dbcommands.c
src/backend/utils/activity/wait_event.c
src/include/utils/wait_event.h

index 5cfdc70c03fd1a1cf7511406251740fe7492924c..d16da9c18779a60c4cafa6906c241af10320de0d 100644 (file)
@@ -1545,6 +1545,11 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
       <entry><literal>TwophaseFileWrite</literal></entry>
       <entry>Waiting for a write of a two phase state file.</entry>
      </row>
+     <row>
+      <entry><literal>VersionFileSync</literal></entry>
+      <entry>Waiting for the version file to reach durable storage while
+       creating a database.</entry>
+     </row>
      <row>
       <entry><literal>VersionFileWrite</literal></entry>
       <entry>Waiting for the version file to be written while creating a database.</entry>
index 18a5868567b516a2e9a048d5cc739f409a439c45..aa48fdf8d21f20f1a4c1cd9349d8befb5268cca4 100644 (file)
@@ -508,6 +508,14 @@ CreateDirAndVersionFile(char *dbpath, Oid dbid, Oid tsid, bool isRedo)
    }
    pgstat_report_wait_end();
 
+   pgstat_report_wait_start(WAIT_EVENT_VERSION_FILE_SYNC);
+   if (pg_fsync(fd) != 0)
+       ereport(data_sync_elevel(ERROR),
+               (errcode_for_file_access(),
+                errmsg("could not fsync file \"%s\": %m", versionfile)));
+   fsync_fname(dbpath, true);
+   pgstat_report_wait_end();
+
    /* Close the version file. */
    CloseTransientFile(fd);
 
index 7940d646392b3625aedbc8ec3729d291cec0f677..05b71f9bc2a0f3cc0b4a1f0f714db52eebd2ad03 100644 (file)
@@ -717,6 +717,9 @@ pgstat_get_wait_io(WaitEventIO w)
        case WAIT_EVENT_TWOPHASE_FILE_WRITE:
            event_name = "TwophaseFileWrite";
            break;
+       case WAIT_EVENT_VERSION_FILE_SYNC:
+           event_name = "VersionFileSync";
+           break;
        case WAIT_EVENT_VERSION_FILE_WRITE:
            event_name = "VersionFileWrite";
            break;
index 518d3b0a1f768ef87e7ac1577248769f5236d7e1..2adc5df2e79b0c299aa86b2c93241135b38c5189 100644 (file)
@@ -234,7 +234,8 @@ typedef enum
    WAIT_EVENT_WAL_READ,
    WAIT_EVENT_WAL_SYNC,
    WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN,
-   WAIT_EVENT_WAL_WRITE
+   WAIT_EVENT_WAL_WRITE,
+   WAIT_EVENT_VERSION_FILE_SYNC
 } WaitEventIO;