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. ]
This commit is contained in:
Bruce Momjian 2012-12-03 22:47:59 -05:00
parent 25d1ed04a2
commit 630cd14426
5 changed files with 47 additions and 5 deletions

View File

@ -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);

View File

@ -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);
/*

View File

@ -1696,6 +1696,15 @@ include 'filename'
turning off <varname>fsync</varname>.
</para>
<para>
For reliable recovery when changing <varname>fsync</varname>
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 <command>initdb
--sync-only</command>, running <command>sync</>, unmounting the
file system, or rebooting the server.
</para>
<para>
In many situations, turning off <xref linkend="guc-synchronous-commit">
for noncritical transactions can provide much of the potential

View File

@ -244,6 +244,17 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>-S</option></term>
<term><option>--sync-only</option></term>
<listitem>
<para>
Safely write all database files to disk and exit. This does not
perform any of the normal <application>initdb</> operations.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-T <replaceable>CFG</></option></term>
<term><option>--text-search-config=<replaceable>CFG</></option></term>

View File

@ -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);