static bool streamwal = false;
static bool fastcheckpoint = false;
static bool writerecoveryconf = false;
+static bool do_sync = true;
static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
static pg_time_t last_progress_report = 0;
static int32 maxrate = 0; /* no limit by default */
" set fast or spread checkpointing\n"));
printf(_(" -l, --label=LABEL set backup label\n"));
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(_(" -P, --progress show progress information\n"));
printf(_(" -v, --verbose output verbose messages\n"));
printf(_(" -V, --version output version information, then exit\n"));
stream.stream_stop = reached_end_position;
stream.standby_message_timeout = standby_message_timeout;
stream.synchronous = false;
+ stream.do_sync = do_sync;
stream.mark_done = true;
stream.basedir = param->xlogdir;
stream.partial_suffix = NULL;
PQfreemem(copybuf);
/* sync the resulting tar file, errors are not considered fatal */
- if (strcmp(basedir, "-") != 0)
+ if (do_sync && strcmp(basedir, "-") != 0)
(void) fsync_fname(filename, false, progname);
}
* all the data of the base directory is synced, taking into account
* all the tablespaces. Errors are not considered fatal.
*/
- if (format == 't')
+ if (do_sync)
{
- if (strcmp(basedir, "-") != 0)
- (void) fsync_fname(basedir, true, progname);
- }
- else
- {
- (void) fsync_pgdata(basedir, progname);
+ if (format == 't')
+ {
+ if (strcmp(basedir, "-") != 0)
+ (void) fsync_fname(basedir, true, progname);
+ }
+ else
+ {
+ (void) fsync_pgdata(basedir, progname);
+ }
}
if (verbose)
{"compress", required_argument, NULL, 'Z'},
{"label", required_argument, NULL, 'l'},
{"noclean", no_argument, NULL, 'n'},
+ {"nosync", no_argument, NULL, 'N'},
{"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
atexit(cleanup_directories_atexit);
- while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:nzZ:d:c:h:p:U:s:S:wWvP",
+ while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:nNzZ:d:c:h:p:U:s:S:wWvP",
long_options, &option_index)) != -1)
{
switch (c)
case 'n':
noclean = true;
break;
+ case 'N':
+ do_sync = false;
+ break;
case 'z':
#ifdef HAVE_LIBZ
compresslevel = Z_DEFAULT_COMPRESSION;
XLogRecPtr *stoppos);
static int CopyStreamPoll(PGconn *conn, long timeout_ms);
static int CopyStreamReceive(PGconn *conn, long timeout, char **buffer);
-static bool ProcessKeepaliveMsg(PGconn *conn, char *copybuf, int len,
- XLogRecPtr blockpos, int64 *last_status);
+static bool ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf,
+ int len, XLogRecPtr blockpos, int64 *last_status);
static bool ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
XLogRecPtr *blockpos);
static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf,
uint32 *timeline);
static bool
-mark_file_as_archived(const char *basedir, const char *fname)
+mark_file_as_archived(const char *basedir, const char *fname, bool do_sync)
{
int fd;
static char tmppath[MAXPGPATH];
close(fd);
- if (fsync_fname(tmppath, false, progname) != 0)
+ if (do_sync && fsync_fname(tmppath, false, progname) != 0)
return false;
- if (fsync_parent_path(tmppath, progname) != 0)
+ if (do_sync && fsync_parent_path(tmppath, progname) != 0)
return false;
return true;
* fsync, in case of a previous crash between padding and fsyncing the
* file.
*/
- if (fsync_fname(fn, false, progname) != 0)
+ if (stream->do_sync && fsync_fname(fn, false, progname) != 0)
return false;
- if (fsync_parent_path(fn, progname) != 0)
+ if (stream->do_sync && fsync_parent_path(fn, progname) != 0)
return false;
return true;
* using synchronous mode, where the file is modified and fsynced
* in-place, without a directory fsync.
*/
- if (fsync_fname(fn, false, progname) != 0)
+ if (stream->do_sync && fsync_fname(fn, false, progname) != 0)
return false;
- if (fsync_parent_path(fn, progname) != 0)
+ if (stream->do_sync && fsync_parent_path(fn, progname) != 0)
return false;
if (lseek(f, SEEK_SET, 0) != 0)
return false;
}
- if (fsync(walfile) != 0)
+ if (stream->do_sync && fsync(walfile) != 0)
{
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
progname, current_walfile_name, strerror(errno));
if (currpos == XLOG_SEG_SIZE && stream->mark_done)
{
/* writes error message if failed */
- if (!mark_file_as_archived(stream->basedir, current_walfile_name))
+ if (!mark_file_as_archived(stream->basedir, current_walfile_name,
+ stream->do_sync))
return false;
}
if (stream->mark_done)
{
/* writes error message if failed */
- if (!mark_file_as_archived(stream->basedir, histfname))
+ if (!mark_file_as_archived(stream->basedir, histfname,
+ stream->do_sync))
return false;
}
*/
if (stream->synchronous && lastFlushPosition < blockpos && walfile != -1)
{
- if (fsync(walfile) != 0)
+ if (stream->do_sync && fsync(walfile) != 0)
{
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
progname, current_walfile_name, strerror(errno));
/* Check the message type. */
if (copybuf[0] == 'k')
{
- if (!ProcessKeepaliveMsg(conn, copybuf, r, blockpos,
+ if (!ProcessKeepaliveMsg(conn, stream, copybuf, r, blockpos,
&last_status))
goto error;
}
* Process the keepalive message.
*/
static bool
-ProcessKeepaliveMsg(PGconn *conn, char *copybuf, int len,
+ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
XLogRecPtr blockpos, int64 *last_status)
{
int pos;
* data has been successfully replicated or not, at the normal
* shutdown of the server.
*/
- if (fsync(walfile) != 0)
+ if (stream->do_sync && fsync(walfile) != 0)
{
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
progname, current_walfile_name, strerror(errno));