diff options
| author | Heikki Linnakangas | 2013-01-17 18:23:00 +0000 |
|---|---|---|
| committer | Heikki Linnakangas | 2013-01-17 18:23:00 +0000 |
| commit | 0b6329130e8e4576e97ff763f0e773347e1a88af (patch) | |
| tree | 7902ba1fa99ac8124232122ce16231cff0b0e21e /src/bin/pg_basebackup/pg_basebackup.c | |
| parent | 8ae35e91807508872cabd3b0e8db35fc78e194ac (diff) | |
Make pg_receivexlog and pg_basebackup -X stream work across timeline switches.
This mirrors the changes done earlier to the server in standby mode. When
receivelog reaches the end of a timeline, as reported by the server, it
fetches the timeline history file of the next timeline, and restarts
streaming from the new timeline by issuing a new START_STREAMING command.
When pg_receivexlog crosses a timeline, it leaves the .partial suffix on the
last segment on the old timeline. This helps you to tell apart a partial
segment left in the directory because of a timeline switch, and a completed
segment. If you just follow a single server, it won't make a difference, but
it can be significant in more complicated scenarios where new WAL is still
generated on the old timeline.
This includes two small changes to the streaming replication protocol:
First, when you reach the end of timeline while streaming, the server now
sends the TLI of the next timeline in the server's history to the client.
pg_receivexlog uses that as the next timeline, so that it doesn't need to
parse the timeline history file like a standby server does. Second, when
BASE_BACKUP command sends the begin and end WAL positions, it now also sends
the timeline IDs corresponding the positions.
Diffstat (limited to 'src/bin/pg_basebackup/pg_basebackup.c')
| -rw-r--r-- | src/bin/pg_basebackup/pg_basebackup.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index a684c0c6fcf..b6f774469b1 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -243,7 +243,7 @@ LogStreamerMain(logstreamer_param *param) if (!ReceiveXlogStream(param->bgconn, param->startptr, param->timeline, param->sysidentifier, param->xlogdir, reached_end_position, standby_message_timeout, - true)) + NULL)) /* * Any errors will already have been reported in the function process, @@ -1220,7 +1220,7 @@ BaseBackup(void) { PGresult *res; char *sysidentifier; - uint32 timeline; + uint32 starttli; char current_path[MAXPGPATH]; char escaped_label[MAXPGPATH]; int i; @@ -1259,7 +1259,6 @@ BaseBackup(void) disconnect_and_exit(1); } sysidentifier = pg_strdup(PQgetvalue(res, 0, 0)); - timeline = atoi(PQgetvalue(res, 0, 1)); PQclear(res); /* @@ -1291,18 +1290,24 @@ BaseBackup(void) progname, PQerrorMessage(conn)); disconnect_and_exit(1); } - if (PQntuples(res) != 1) + if (PQntuples(res) != 1 || PQnfields(res) < 2) { - fprintf(stderr, _("%s: no start point returned from server\n"), - progname); + fprintf(stderr, + _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"), + progname, PQntuples(res), PQnfields(res), 1, 2); disconnect_and_exit(1); } + strcpy(xlogstart, PQgetvalue(res, 0, 0)); - if (verbose && includewal) - fprintf(stderr, "transaction log start point: %s\n", xlogstart); + starttli = atoi(PQgetvalue(res, 0, 1)); + PQclear(res); MemSet(xlogend, 0, sizeof(xlogend)); + if (verbose && includewal) + fprintf(stderr, _("transaction log start point: %s on timeline %u\n"), + xlogstart, starttli); + /* * Get the header */ @@ -1358,7 +1363,7 @@ BaseBackup(void) if (verbose) fprintf(stderr, _("%s: starting background WAL receiver\n"), progname); - StartLogStreamer(xlogstart, timeline, sysidentifier); + StartLogStreamer(xlogstart, starttli, sysidentifier); } /* |
