Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6ed2d85

Browse files
committed
pg_basebackup: Add --nosync option
This is useful for testing, similar to initdb's --nosync. From: Michael Paquier <michael.paquier@gmail.com>
1 parent bc34223 commit 6ed2d85

File tree

5 files changed

+56
-26
lines changed

5 files changed

+56
-26
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,21 @@ PostgreSQL documentation
438438
</listitem>
439439
</varlistentry>
440440

441+
<varlistentry>
442+
<term><option>-N</option></term>
443+
<term><option>--nosync</option></term>
444+
<listitem>
445+
<para>
446+
By default, <command>pg_basebackup</command> will wait for all files
447+
to be written safely to disk. This option causes
448+
<command>pg_basebackup</command> to return without waiting, which is
449+
faster, but means that a subsequent operating system crash can leave
450+
the base backup corrupt. Generally, this option is useful for testing
451+
but should not be used when creating a production installation.
452+
</para>
453+
</listitem>
454+
</varlistentry>
455+
441456
<varlistentry>
442457
<term><option>-v</option></term>
443458
<term><option>--verbose</option></term>

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static bool includewal = false;
6969
static bool streamwal = false;
7070
static bool fastcheckpoint = false;
7171
static bool writerecoveryconf = false;
72+
static bool do_sync = true;
7273
static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
7374
static pg_time_t last_progress_report = 0;
7475
static int32 maxrate = 0; /* no limit by default */
@@ -329,6 +330,7 @@ usage(void)
329330
" set fast or spread checkpointing\n"));
330331
printf(_(" -l, --label=LABEL set backup label\n"));
331332
printf(_(" -n, --noclean do not clean up after errors\n"));
333+
printf(_(" -N, --nosync do not wait for changes to be written safely to disk\n"));
332334
printf(_(" -P, --progress show progress information\n"));
333335
printf(_(" -v, --verbose output verbose messages\n"));
334336
printf(_(" -V, --version output version information, then exit\n"));
@@ -460,6 +462,7 @@ LogStreamerMain(logstreamer_param *param)
460462
stream.stream_stop = reached_end_position;
461463
stream.standby_message_timeout = standby_message_timeout;
462464
stream.synchronous = false;
465+
stream.do_sync = do_sync;
463466
stream.mark_done = true;
464467
stream.basedir = param->xlogdir;
465468
stream.partial_suffix = NULL;
@@ -1199,7 +1202,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
11991202
PQfreemem(copybuf);
12001203

12011204
/* sync the resulting tar file, errors are not considered fatal */
1202-
if (strcmp(basedir, "-") != 0)
1205+
if (do_sync && strcmp(basedir, "-") != 0)
12031206
(void) fsync_fname(filename, false, progname);
12041207
}
12051208

@@ -1967,14 +1970,17 @@ BaseBackup(void)
19671970
* all the data of the base directory is synced, taking into account
19681971
* all the tablespaces. Errors are not considered fatal.
19691972
*/
1970-
if (format == 't')
1973+
if (do_sync)
19711974
{
1972-
if (strcmp(basedir, "-") != 0)
1973-
(void) fsync_fname(basedir, true, progname);
1974-
}
1975-
else
1976-
{
1977-
(void) fsync_pgdata(basedir, progname);
1975+
if (format == 't')
1976+
{
1977+
if (strcmp(basedir, "-") != 0)
1978+
(void) fsync_fname(basedir, true, progname);
1979+
}
1980+
else
1981+
{
1982+
(void) fsync_pgdata(basedir, progname);
1983+
}
19781984
}
19791985

19801986
if (verbose)
@@ -2001,6 +2007,7 @@ main(int argc, char **argv)
20012007
{"compress", required_argument, NULL, 'Z'},
20022008
{"label", required_argument, NULL, 'l'},
20032009
{"noclean", no_argument, NULL, 'n'},
2010+
{"nosync", no_argument, NULL, 'N'},
20042011
{"dbname", required_argument, NULL, 'd'},
20052012
{"host", required_argument, NULL, 'h'},
20062013
{"port", required_argument, NULL, 'p'},
@@ -2037,7 +2044,7 @@ main(int argc, char **argv)
20372044

20382045
atexit(cleanup_directories_atexit);
20392046

2040-
while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:nzZ:d:c:h:p:U:s:S:wWvP",
2047+
while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:nNzZ:d:c:h:p:U:s:S:wWvP",
20412048
long_options, &option_index)) != -1)
20422049
{
20432050
switch (c)
@@ -2115,6 +2122,9 @@ main(int argc, char **argv)
21152122
case 'n':
21162123
noclean = true;
21172124
break;
2125+
case 'N':
2126+
do_sync = false;
2127+
break;
21182128
case 'z':
21192129
#ifdef HAVE_LIBZ
21202130
compresslevel = Z_DEFAULT_COMPRESSION;

src/bin/pg_basebackup/pg_receivexlog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ StreamLog(void)
336336
stream.stream_stop = stop_streaming;
337337
stream.standby_message_timeout = standby_message_timeout;
338338
stream.synchronous = synchronous;
339+
stream.do_sync = true;
339340
stream.mark_done = false;
340341
stream.basedir = basedir;
341342
stream.partial_suffix = ".partial";

src/bin/pg_basebackup/receivelog.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ static PGresult *HandleCopyStream(PGconn *conn, StreamCtl *stream,
4141
XLogRecPtr *stoppos);
4242
static int CopyStreamPoll(PGconn *conn, long timeout_ms);
4343
static int CopyStreamReceive(PGconn *conn, long timeout, char **buffer);
44-
static bool ProcessKeepaliveMsg(PGconn *conn, char *copybuf, int len,
45-
XLogRecPtr blockpos, int64 *last_status);
44+
static bool ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf,
45+
int len, XLogRecPtr blockpos, int64 *last_status);
4646
static bool ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
4747
XLogRecPtr *blockpos);
4848
static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf,
@@ -56,7 +56,7 @@ static bool ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos,
5656
uint32 *timeline);
5757

5858
static bool
59-
mark_file_as_archived(const char *basedir, const char *fname)
59+
mark_file_as_archived(const char *basedir, const char *fname, bool do_sync)
6060
{
6161
int fd;
6262
static char tmppath[MAXPGPATH];
@@ -74,10 +74,10 @@ mark_file_as_archived(const char *basedir, const char *fname)
7474

7575
close(fd);
7676

77-
if (fsync_fname(tmppath, false, progname) != 0)
77+
if (do_sync && fsync_fname(tmppath, false, progname) != 0)
7878
return false;
7979

80-
if (fsync_parent_path(tmppath, progname) != 0)
80+
if (do_sync && fsync_parent_path(tmppath, progname) != 0)
8181
return false;
8282

8383
return true;
@@ -134,9 +134,9 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
134134
* fsync, in case of a previous crash between padding and fsyncing the
135135
* file.
136136
*/
137-
if (fsync_fname(fn, false, progname) != 0)
137+
if (stream->do_sync && fsync_fname(fn, false, progname) != 0)
138138
return false;
139-
if (fsync_parent_path(fn, progname) != 0)
139+
if (stream->do_sync && fsync_parent_path(fn, progname) != 0)
140140
return false;
141141

142142
return true;
@@ -173,9 +173,9 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
173173
* using synchronous mode, where the file is modified and fsynced
174174
* in-place, without a directory fsync.
175175
*/
176-
if (fsync_fname(fn, false, progname) != 0)
176+
if (stream->do_sync && fsync_fname(fn, false, progname) != 0)
177177
return false;
178-
if (fsync_parent_path(fn, progname) != 0)
178+
if (stream->do_sync && fsync_parent_path(fn, progname) != 0)
179179
return false;
180180

181181
if (lseek(f, SEEK_SET, 0) != 0)
@@ -212,7 +212,7 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
212212
return false;
213213
}
214214

215-
if (fsync(walfile) != 0)
215+
if (stream->do_sync && fsync(walfile) != 0)
216216
{
217217
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
218218
progname, current_walfile_name, strerror(errno));
@@ -258,7 +258,8 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
258258
if (currpos == XLOG_SEG_SIZE && stream->mark_done)
259259
{
260260
/* writes error message if failed */
261-
if (!mark_file_as_archived(stream->basedir, current_walfile_name))
261+
if (!mark_file_as_archived(stream->basedir, current_walfile_name,
262+
stream->do_sync))
262263
return false;
263264
}
264265

@@ -378,7 +379,8 @@ writeTimeLineHistoryFile(StreamCtl *stream, char *filename, char *content)
378379
if (stream->mark_done)
379380
{
380381
/* writes error message if failed */
381-
if (!mark_file_as_archived(stream->basedir, histfname))
382+
if (!mark_file_as_archived(stream->basedir, histfname,
383+
stream->do_sync))
382384
return false;
383385
}
384386

@@ -836,7 +838,7 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream,
836838
*/
837839
if (stream->synchronous && lastFlushPosition < blockpos && walfile != -1)
838840
{
839-
if (fsync(walfile) != 0)
841+
if (stream->do_sync && fsync(walfile) != 0)
840842
{
841843
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
842844
progname, current_walfile_name, strerror(errno));
@@ -890,7 +892,7 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream,
890892
/* Check the message type. */
891893
if (copybuf[0] == 'k')
892894
{
893-
if (!ProcessKeepaliveMsg(conn, copybuf, r, blockpos,
895+
if (!ProcessKeepaliveMsg(conn, stream, copybuf, r, blockpos,
894896
&last_status))
895897
goto error;
896898
}
@@ -1043,7 +1045,7 @@ CopyStreamReceive(PGconn *conn, long timeout, char **buffer)
10431045
* Process the keepalive message.
10441046
*/
10451047
static bool
1046-
ProcessKeepaliveMsg(PGconn *conn, char *copybuf, int len,
1048+
ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
10471049
XLogRecPtr blockpos, int64 *last_status)
10481050
{
10491051
int pos;
@@ -1079,7 +1081,7 @@ ProcessKeepaliveMsg(PGconn *conn, char *copybuf, int len,
10791081
* data has been successfully replicated or not, at the normal
10801082
* shutdown of the server.
10811083
*/
1082-
if (fsync(walfile) != 0)
1084+
if (stream->do_sync && fsync(walfile) != 0)
10831085
{
10841086
fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
10851087
progname, current_walfile_name, strerror(errno));

src/bin/pg_basebackup/receivelog.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ typedef struct StreamCtl
3434
* timeline */
3535
int standby_message_timeout; /* Send status messages this
3636
* often */
37-
bool synchronous; /* Flush data on write */
37+
bool synchronous; /* Flush immediately WAL data on write */
3838
bool mark_done; /* Mark segment as done in generated archive */
39+
bool do_sync; /* Flush to disk to ensure consistent state
40+
* of data */
3941

4042
stream_stop_callback stream_stop; /* Stop streaming when returns true */
4143

0 commit comments

Comments
 (0)