On Linux, syncfs may be used instead, to ask the
operating system to synchronize the whole file systems that contain the
data directory, the WAL files and each tablespace (but not any other
- file systems that may be reachable through symbolic links). This may
- be a lot faster than the fsync setting, because it
- doesn't need to open each file one by one. On the other hand, it may
- be slower if a file system is shared by other applications that
- modify a lot of files, since those files will also be written to disk.
- Furthermore, on versions of Linux before 5.8, I/O errors encountered
- while writing data to disk may not be reported to
-
PostgreSQL , and relevant error messages may
- appear only in kernel logs.
+ file systems that may be reachable through symbolic links). See
+ for more information about using
+ syncfs() .
This parameter can only be set in the
&acronyms;
&glossary;
&color;
+ &syncfs;
&obsolete;
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ initdb will recursively open and synchronize all
+ files in the data directory. The search for files will follow symbolic
+ links for the WAL directory and each configured tablespace.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file systems that contain the
+ data directory, the WAL files, and each tablespace. See
+ for more information about using
+ syncfs() .
+
+ This option has no effect when --no-sync is used.
+
+
+
+
-S
--sync-only
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ pg_basebackup will recursively open and synchronize
+ all files in the backup directory. When the plain format is used, the
+ search for files will follow symbolic links for the WAL directory and
+ each configured tablespace.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file system that contains the
+ backup directory. When the plain format is used,
+ pg_basebackup will also synchronize the file systems
+ that contain the WAL files and each tablespace. See
+ for more information about using
+ syncfs() .
+
+ This option has no effect when --no-sync is used.
+
+
+
+
-v
--verbose
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ pg_checksums will recursively open and synchronize
+ all files in the data directory. The search for files will follow
+ symbolic links for the WAL directory and each configured tablespace.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file systems that contain the
+ data directory, the WAL files, and each tablespace. See
+ for more information about using
+ syncfs() .
+
+ This option has no effect when --no-sync is used.
+
+
+
+
-v
--verbose
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ pg_dump --format=directory will recursively open and
+ synchronize all files in the archive directory.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file system that contains the
+ archive directory. See for more information
+ about using syncfs() .
+
+ This option has no effect when --no-sync is used or
+ --format is not set to directory .
+
+
+
+
--table-and-children=pattern
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ pg_rewind will recursively open and synchronize all
+ files in the data directory. The search for files will follow symbolic
+ links for the WAL directory and each configured tablespace.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file systems that contain the
+ data directory, the WAL files, and each tablespace. See
+ for more information about using
+ syncfs() .
+
+ This option has no effect when --no-sync is used.
+
+
+
+
-V
--version
variable PGSOCKETDIR
+
+ --sync-method
+
+ When set to fsync , which is the default,
+ pg_upgrade will recursively open and synchronize all
+ files in the upgraded cluster's data directory. The search for files
+ will follow symbolic links for the WAL directory and each configured
+ tablespace.
+
+ On Linux, syncfs may be used instead to ask the
+ operating system to synchronize the whole file systems that contain the
+ upgraded cluster's data directory, its WAL files, and each tablespace.
+ See for more information about using
+ syncfs() .
+
+ This option has no effect when --no-sync is used.
+
+
+
+
-U username
--username= username
--- /dev/null
+
+
+
syncfs() Caveats
+
+
+
+
+ On Linux syncfs() may be specified for some
+ configuration parameters (e.g.,
+ ), server applications (e.g.,
+
pg_upgrade ), and client applications (e.g.,
+
pg_basebackup ) that involve synchronizing many
+ files to disk. syncfs() is advantageous in many cases,
+ but there are some trade-offs to keep in mind.
+
+
+ Since syncfs() instructs the operating system to
+ synchronize a whole file system, it typically requires many fewer system
+ calls than using fsync() to synchronize each file one by
+ one. Therefore, using syncfs() may be a lot faster than
+ using fsync() . However, it may be slower if a file
+ system is shared by other applications that modify a lot of files, since
+ those files will also be written to disk.
+
+
+ Furthermore, on versions of Linux before 5.8, I/O errors encountered while
+ writing data to disk may not be reported to the calling program, and relevant
+ error messages may appear only in kernel logs.
+
+
+
printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
printf(_(" --no-instructions do not print instructions for next steps\n"));
printf(_(" -s, --show show internal settings\n"));
+ printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -S, --sync-only only sync database files to disk, then exit\n"));
printf(_("\nOther options:\n"));
printf(_(" -V, --version output version information, then exit\n"));
{"locale-provider", required_argument, NULL, 15},
{"icu-locale", required_argument, NULL, 16},
{"icu-rules", required_argument, NULL, 17},
+ {"sync-method", required_argument, NULL, 18},
{NULL, 0, NULL, 0}
};
case 17:
icu_rules = pg_strdup(optarg);
break;
+ case 18:
+ if (!parse_sync_method(optarg, &sync_method))
+ exit(1);
+ break;
default:
/* getopt_long already emitted a complaint */
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
my $tempdir = PostgreSQL::Test::Utils::tempdir;
my $xlogdir = "$tempdir/pgxlog";
my $datadir = "$tempdir/data";
+my $supports_syncfs = check_pg_config("#define HAVE_SYNCFS 1");
program_help_ok('initdb');
program_version_ok('initdb');
command_ok([ 'initdb', '-S', $datadir ], 'sync only');
command_fails([ 'initdb', $datadir ], 'existing data directory');
+if ($supports_syncfs)
+{
+ command_ok([ 'initdb', '-S', $datadir, '--sync-method', 'syncfs' ],
+ 'sync method syncfs');
+}
+else
+{
+ command_fails([ 'initdb', '-S', $datadir, '--sync-method', 'syncfs' ],
+ 'sync method syncfs');
+}
+
# Check group access on PGDATA
SKIP:
{
printf(_(" --no-slot prevent creation of temporary replication slot\n"));
printf(_(" --no-verify-checksums\n"
" do not verify checksums\n"));
+ printf(_(" --sync-method=METHOD\n"
+ " set method for syncing files to disk\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
printf(_(" -d, --dbname=CONNSTR connection string\n"));
{"no-manifest", no_argument, NULL, 5},
{"manifest-force-encode", no_argument, NULL, 6},
{"manifest-checksums", required_argument, NULL, 7},
+ {"sync-method", required_argument, NULL, 8},
{NULL, 0, NULL, 0}
};
int c;
case 7:
manifest_checksums = pg_strdup(optarg);
break;
+ case 8:
+ if (!parse_sync_method(optarg, &sync_method))
+ exit(1);
+ break;
default:
/* getopt_long already emitted a complaint */
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
printf(_(" -f, --filenode=FILENODE check only relation with specified filenode\n"));
printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
printf(_(" -P, --progress show progress information\n"));
+ printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -v, --verbose output verbose messages\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
{"no-sync", no_argument, NULL, 'N'},
{"progress", no_argument, NULL, 'P'},
{"verbose", no_argument, NULL, 'v'},
+ {"sync-method", required_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
case 'v':
verbose = true;
break;
+ case 1:
+ if (!parse_sync_method(optarg, &sync_method))
+ exit(1);
+ break;
default:
/* getopt_long already emitted a complaint */
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
{"table-and-children", required_argument, NULL, 12},
{"exclude-table-and-children", required_argument, NULL, 13},
{"exclude-table-data-and-children", required_argument, NULL, 14},
+ {"sync-method", required_argument, NULL, 15},
{NULL, 0, NULL, 0}
};
optarg);
break;
+ case 15:
+ if (!parse_sync_method(optarg, &sync_method))
+ exit_nicely(1);
+ break;
+
default:
/* getopt_long already emitted a complaint */
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
" compress as specified\n"));
printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
+ printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nOptions controlling the output content:\n"));
#include "common/file_perm.h"
#include "common/restricted_token.h"
#include "common/string.h"
+#include "fe_utils/option_utils.h"
#include "fe_utils/recovery_gen.h"
#include "fe_utils/string_utils.h"
#include "file_ops.h"
" file when running target cluster\n"));
printf(_(" --debug write a lot of debug messages\n"));
printf(_(" --no-ensure-shutdown do not automatically fix unclean shutdown\n"));
+ printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
{"no-sync", no_argument, NULL, 'N'},
{"progress", no_argument, NULL, 'P'},
{"debug", no_argument, NULL, 3},
+ {"sync-method", required_argument, NULL, 6},
{NULL, 0, NULL, 0}
};
int option_index;
config_file = pg_strdup(optarg);
break;
+ case 6:
+ if (!parse_sync_method(optarg, &sync_method))
+ exit(1);
+ break;
+
default:
/* getopt_long already emitted a complaint */
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
#endif
#include "common/string.h"
+#include "fe_utils/option_utils.h"
#include "getopt_long.h"
#include "pg_upgrade.h"
#include "utils/pidfile.h"
{"verbose", no_argument, NULL, 'v'},
{"clone", no_argument, NULL, 1},
{"copy", no_argument, NULL, 2},
+ {"sync-method", required_argument, NULL, 3},
{NULL, 0, NULL, 0}
};
int option; /* Command line option */
int optindex = 0; /* used by getopt_long */
int os_user_effective_id;
+ DataDirSyncMethod unused;
user_opts.do_sync = true;
user_opts.transfer_mode = TRANSFER_MODE_COPY;
user_opts.transfer_mode = TRANSFER_MODE_COPY;
break;
+ case 3:
+ if (!parse_sync_method(optarg, &unused))
+ exit(1);
+ user_opts.sync_method = pg_strdup(optarg);
+ break;
+
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
os_info.progname);
if (optind < argc)
pg_fatal("too many command-line arguments (first is \"%s\")", argv[optind]);
+ if (!user_opts.sync_method)
+ user_opts.sync_method = pg_strdup("fsync");
+
if (log_opts.verbose)
pg_log(PG_REPORT, "Running in verbose mode");
printf(_(" -V, --version display version information, then exit\n"));
printf(_(" --clone clone instead of copying files to new cluster\n"));
printf(_(" --copy copy files to new cluster (default)\n"));
+ printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\n"
"Before running pg_upgrade you must:\n"
{
prep_status("Sync data directory to disk");
exec_prog(UTILITY_LOG_FILE, NULL, true, true,
- "\"%s/initdb\" --sync-only \"%s\"", new_cluster.bindir,
- new_cluster.pgdata);
+ "\"%s/initdb\" --sync-only \"%s\" --sync-method %s",
+ new_cluster.bindir,
+ new_cluster.pgdata,
+ user_opts.sync_method);
check_ok();
}
transferMode transfer_mode; /* copy files or link them? */
int jobs; /* number of processes/threads to use */
char *socketdir; /* directory to use for Unix sockets */
+ char *sync_method;
} UserOpts;
typedef struct
*result = val;
return true;
}
+
+/*
+ * Provide strictly harmonized handling of the --sync-method option.
+ */
+bool
+parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
+{
+ if (strcmp(optarg, "fsync") == 0)
+ *sync_method = DATA_DIR_SYNC_METHOD_FSYNC;
+ else if (strcmp(optarg, "syncfs") == 0)
+ {
+#ifdef HAVE_SYNCFS
+ *sync_method = DATA_DIR_SYNC_METHOD_SYNCFS;
+#else
+ pg_log_error("this build does not support sync method \"%s\"",
+ "syncfs");
+ return false;
+#endif
+ }
+ else
+ {
+ pg_log_error("unrecognized sync method: %s", optarg);
+ return false;
+ }
+
+ return true;
+}
#include "postgres_fe.h"
+#include "common/file_utils.h"
+
typedef void (*help_handler) (const char *progname);
extern void handle_help_version_opts(int argc, char *argv[],
extern bool option_parse_int(const char *optarg, const char *optname,
int min_range, int max_range,
int *result);
+extern bool parse_sync_method(const char *optarg,
+ DataDirSyncMethod *sync_method);
#endif /* OPTION_UTILS_H */