diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c new file mode 100644 index c12f15b..63df529 *** a/contrib/pg_upgrade/pg_upgrade.c --- b/contrib/pg_upgrade/pg_upgrade.c *************** main(int argc, char **argv) *** 150,155 **** --- 150,161 ---- new_cluster.pgdata); check_ok(); + prep_status("Sync data directory to disk"); + exec_prog(UTILITY_LOG_FILE, NULL, true, + "\"%s/initdb\" --sync-only \"%s\"", new_cluster.bindir, + new_cluster.pgdata); + check_ok(); + create_script_for_cluster_analyze(&analyze_script_file_name); create_script_for_old_cluster_deletion(&deletion_script_file_name); diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c new file mode 100644 index 49d4c8f..05d8cc0 *** a/contrib/pg_upgrade/server.c --- b/contrib/pg_upgrade/server.c *************** start_postmaster(ClusterInfo *cluster) *** 209,217 **** * a gap of 2000000000 from the current xid counter, so autovacuum will * not touch them. * ! * synchronous_commit=off improves object creation speed, and we only ! * modify the new cluster, so only use it there. If there is a crash, ! * the new cluster has to be recreated anyway. */ snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s%s%s\" start", --- 209,217 ---- * a gap of 2000000000 from the current xid counter, so autovacuum will * not touch them. * ! * Turn off durability requirements to improve object creation speed, and ! * we only modify the new cluster, so only use it there. If there is a ! * crash, the new cluster has to be recreated anyway. */ snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s%s%s\" start", *************** start_postmaster(ClusterInfo *cluster) *** 219,225 **** (cluster->controldata.cat_ver >= BINARY_UPGRADE_SERVER_FLAG_CAT_VER) ? " -b" : " -c autovacuum=off -c autovacuum_freeze_max_age=2000000000", ! (cluster == &new_cluster) ? " -c synchronous_commit=off" : "", cluster->pgopts ? cluster->pgopts : "", socket_string); /* --- 219,226 ---- (cluster->controldata.cat_ver >= BINARY_UPGRADE_SERVER_FLAG_CAT_VER) ? " -b" : " -c autovacuum=off -c autovacuum_freeze_max_age=2000000000", ! (cluster == &new_cluster) ? ! " -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "", cluster->pgopts ? cluster->pgopts : "", socket_string); /* diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml new file mode 100644 index b56070b..b7df8ce *** a/doc/src/sgml/config.sgml --- b/doc/src/sgml/config.sgml *************** include 'filename' *** 1697,1702 **** --- 1697,1711 ---- + For reliable recovery when changing fsync + off to on, it is necessary to force all modified buffers in the + kernel to durable storage. This can be done while the cluster + is shutdown or while fsync is on by running initdb + --sync-only, running sync, unmounting the + file system, or rebooting the server. + + + In many situations, turning off for noncritical transactions can provide much of the potential performance benefit of turning off fsync, without diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml new file mode 100644 index 08ee37e..a1e46eb *** a/doc/src/sgml/ref/initdb.sgml --- b/doc/src/sgml/ref/initdb.sgml *************** PostgreSQL documentation *** 245,250 **** --- 245,261 ---- + + + + + Safely write all database files to disk and exit. This does not + perform any of the normal initdb operations. + + + + + diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c new file mode 100644 index 402504b..8c0a9f4 *** a/src/bin/initdb/initdb.c --- b/src/bin/initdb/initdb.c *************** static const char *authmethodlocal = ""; *** 118,123 **** --- 118,124 ---- static bool debug = false; static bool noclean = false; static bool do_sync = true; + static bool sync_only = false; static bool show_setting = false; static char *xlog_dir = ""; *************** usage(const char *progname) *** 2796,2801 **** --- 2797,2803 ---- printf(_(" -n, --noclean do not clean up after errors\n")); printf(_(" -N, --nosync do not wait for changes to be written safely to disk\n")); printf(_(" -s, --show show internal settings\n")); + printf(_(" -S, --sync-only only sync data directory\n")); printf(_("\nOther options:\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_(" -?, --help show this help, then exit\n")); *************** main(int argc, char *argv[]) *** 3445,3450 **** --- 3447,3453 ---- {"show", no_argument, NULL, 's'}, {"noclean", no_argument, NULL, 'n'}, {"nosync", no_argument, NULL, 'N'}, + {"sync-only", no_argument, NULL, 'S'}, {"xlogdir", required_argument, NULL, 'X'}, {NULL, 0, NULL, 0} }; *************** main(int argc, char *argv[]) *** 3476,3482 **** /* process command-line options */ ! while ((c = getopt_long(argc, argv, "dD:E:L:nNU:WA:sT:X:", long_options, &option_index)) != -1) { switch (c) { --- 3479,3485 ---- /* process command-line options */ ! while ((c = getopt_long(argc, argv, "dD:E:L:nNU:WA:sST:X:", long_options, &option_index)) != -1) { switch (c) { *************** main(int argc, char *argv[]) *** 3522,3527 **** --- 3525,3533 ---- case 'N': do_sync = false; break; + case 'S': + sync_only = true; + break; case 'L': share_path = pg_strdup(optarg); break; *************** main(int argc, char *argv[]) *** 3589,3594 **** --- 3595,3608 ---- exit(1); } + /* If we only need to fsync, just to it and exit */ + if (sync_only) + { + setup_pgdata(); + perform_fsync(); + return 0; + } + if (pwprompt && pwfilename) { fprintf(stderr, _("%s: password prompt and password file cannot be specified together\n"), progname);