From 630cd14426dc1daf85163ad417f3a224eb4ac7b0 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 3 Dec 2012 22:47:59 -0500 Subject: [PATCH] Add initdb --sync-only option to sync the data directory to durable storage. Have pg_upgrade use it, and enable server options fsync=off and full_page_writes=off. Document that users turning fsync from off to on should run initdb --sync-only. [ Previous commit was incorrectly applied as a git merge. ] --- contrib/pg_upgrade/pg_upgrade.c | 6 ++++++ contrib/pg_upgrade/server.c | 10 ++++++---- doc/src/sgml/config.sgml | 9 +++++++++ doc/src/sgml/ref/initdb.sgml | 11 +++++++++++ src/bin/initdb/initdb.c | 16 +++++++++++++++- 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index c12f15b875..63df52996d 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -150,6 +150,12 @@ main(int argc, char **argv) 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 index 49d4c8f9d7..db62249637 100644 --- a/contrib/pg_upgrade/server.c +++ b/contrib/pg_upgrade/server.c @@ -209,9 +209,10 @@ start_postmaster(ClusterInfo *cluster) * 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. + * 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. fsync=off is a big + * win on ext4. */ snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s%s%s\" start", @@ -219,7 +220,8 @@ start_postmaster(ClusterInfo *cluster) (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 == &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 index b56070b0fb..b7df8ce612 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1696,6 +1696,15 @@ include 'filename' turning off fsync. + + 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 diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index 08ee37e7d8..a1e46eb4c6 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -244,6 +244,17 @@ PostgreSQL documentation + + + + + + 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 index 402504b257..8c0a9f41ab 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -118,6 +118,7 @@ static const char *authmethodlocal = ""; 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 = ""; @@ -2796,6 +2797,7 @@ usage(const char *progname) 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")); @@ -3445,6 +3447,7 @@ main(int argc, char *argv[]) {"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} }; @@ -3476,7 +3479,7 @@ main(int argc, char *argv[]) /* process command-line options */ - while ((c = getopt_long(argc, argv, "dD:E:L:nNU:WA:sT:X:", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "dD:E:L:nNU:WA:sST:X:", long_options, &option_index)) != -1) { switch (c) { @@ -3522,6 +3525,9 @@ main(int argc, char *argv[]) case 'N': do_sync = false; break; + case 'S': + sync_only = true; + break; case 'L': share_path = pg_strdup(optarg); break; @@ -3589,6 +3595,14 @@ main(int argc, char *argv[]) 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);