mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Prevent WAL files created by pg_basebackup -x/X from being archived again.
WAL (and timeline history) files created by pg_basebackup did not maintain the new base backup's archive status. That's currently not a problem if the new node is used as a standby - but if that node is promoted all still existing files can get archived again. With a high wal_keep_segment settings that can happen a significant time later - which is quite confusing. Change both the backend (for the -x/-X fetch case) and pg_basebackup (for -X stream) itself to always mark WAL/timeline files included in the base backup as .done. That's in line with walreceiver.c doing so. The verbosity of the pg_basebackup changes show pretty clearly that it needs some refactoring, but that'd result in not be backpatchable changes. Backpatch to 9.1 where pg_basebackup was introduced. Discussion: 20141205002854.GE21964@awork2.anarazel.de
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "common/string.h"
|
||||
#include "getopt_long.h"
|
||||
#include "libpq-fe.h"
|
||||
#include "pqexpbuffer.h"
|
||||
@@ -370,7 +371,7 @@ LogStreamerMain(logstreamer_param *param)
|
||||
if (!ReceiveXlogStream(param->bgconn, param->startptr, param->timeline,
|
||||
param->sysidentifier, param->xlogdir,
|
||||
reached_end_position, standby_message_timeout,
|
||||
NULL, false))
|
||||
NULL, false, true))
|
||||
|
||||
/*
|
||||
* Any errors will already have been reported in the function process,
|
||||
@@ -394,6 +395,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
|
||||
logstreamer_param *param;
|
||||
uint32 hi,
|
||||
lo;
|
||||
char statusdir[MAXPGPATH];
|
||||
|
||||
param = pg_malloc0(sizeof(logstreamer_param));
|
||||
param->timeline = timeline;
|
||||
@@ -428,13 +430,23 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
|
||||
/* Error message already written in GetConnection() */
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* Always in plain format, so we can write to basedir/pg_xlog. But the
|
||||
* directory entry in the tar file may arrive later, so make sure it's
|
||||
* created before we start.
|
||||
*/
|
||||
snprintf(param->xlogdir, sizeof(param->xlogdir), "%s/pg_xlog", basedir);
|
||||
verify_dir_is_empty_or_create(param->xlogdir);
|
||||
|
||||
/*
|
||||
* Create pg_xlog/archive_status (and thus pg_xlog) so we can can write to
|
||||
* basedir/pg_xlog as the directory entry in the tar file may arrive
|
||||
* later.
|
||||
*/
|
||||
snprintf(statusdir, sizeof(statusdir), "%s/pg_xlog/archive_status",
|
||||
basedir);
|
||||
|
||||
if (pg_mkdir_p(statusdir, S_IRWXU) != 0 && errno != EEXIST)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("%s: could not create directory \"%s\": %s\n"),
|
||||
progname, statusdir, strerror(errno));
|
||||
disconnect_and_exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start a child process and tell it to start streaming. On Unix, this is
|
||||
@@ -1236,11 +1248,12 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
|
||||
* by the wal receiver process. Also, when transaction
|
||||
* log directory location was specified, pg_xlog has
|
||||
* already been created as a symbolic link before
|
||||
* starting the actual backup. So just ignore failure
|
||||
* on them.
|
||||
* starting the actual backup. So just ignore creation
|
||||
* failures on related directories.
|
||||
*/
|
||||
if ((!streamwal && (strcmp(xlog_dir, "") == 0))
|
||||
|| strcmp(filename + strlen(filename) - 8, "/pg_xlog") != 0)
|
||||
if (!((pg_str_endswith(filename, "/pg_xlog") ||
|
||||
pg_str_endswith(filename, "/archive_status")) &&
|
||||
errno == EEXIST))
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("%s: could not create directory \"%s\": %s\n"),
|
||||
|
||||
Reference in New Issue
Block a user