Sync PG_VERSION file in CREATE DATABASE.
authorNoah Misch
Thu, 1 Feb 2024 21:44:19 +0000 (13:44 -0800)
committerNoah Misch
Thu, 1 Feb 2024 21:44:23 +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[email protected]

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

index c72ad60fa0e7f29c330b2908ca1d3ed3831595df..84e65002ff3dcc6c71a056fd821f30b504520289 100644 (file)
@@ -1519,6 +1519,11 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
       TwophaseFileWrite
       Waiting for a write of a two phase state file.
      
+     
+      VersionFileSync
+      Waiting for the version file to reach durable storage while
+       creating a database.
+     
      
       VersionFileWrite
       Waiting for the version file to be written while creating a database.
index 79c598896333c373f6340f4d746f1ea2e081fb64..5ced6da20b6436dc80f4900632217c40cc0c94e7 100644 (file)
@@ -507,6 +507,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 87c15b9c6f38e0c636d550e1d3cbea920ec6da0b..787525754a2775ada16516dc925c63c2b8cbada2 100644 (file)
@@ -702,6 +702,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 b578e2ec7573ac1fd6ad09509f328bfb8092ccbd..c814918d6cec5a9ee92f4385d18a871f4a7b24c0 100644 (file)
@@ -229,7 +229,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;