summaryrefslogtreecommitdiff
path: root/src/bin/pg_basebackup/pg_receivexlog.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-05-08 20:10:17 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-05-08 20:30:17 +0300
commit2ffa66f4975c99e52984f7ee81b47d137b5b4751 (patch)
treed48756b7959f7bb63d9ea8513ff68e0dfa88d4ed /src/bin/pg_basebackup/pg_receivexlog.c
parentcb953d8b1bf7386ff20300cd80b29b7e8657dcbd (diff)
Fix walsender failure at promotion.
If a standby server has a cascading standby server connected to it, it's possible that WAL has already been sent up to the next WAL page boundary, splitting a WAL record in the middle, when the first standby server is promoted. Don't throw an assertion failure or error in walsender if that happens. Also, fix a variant of the same bug in pg_receivexlog: if it had already received WAL on previous timeline up to a segment boundary, when the upstream standby server is promoted so that the timeline switch record falls on the previous segment, pg_receivexlog would miss the segment containing the timeline switch. To fix that, have walsender send the position of the timeline switch at end-of-streaming, in addition to the next timeline's ID. It was previously assumed that the switch happened exactly where the streaming stopped. Note: this is an incompatible change in the streaming protocol. You might get an error if you try to stream over timeline switches, if the client is running 9.3beta1 and the server is more recent. It should be fine after a reconnect, however. Reported by Fujii Masao.
Diffstat (limited to 'src/bin/pg_basebackup/pg_receivexlog.c')
-rw-r--r--src/bin/pg_basebackup/pg_receivexlog.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/bin/pg_basebackup/pg_receivexlog.c b/src/bin/pg_basebackup/pg_receivexlog.c
index e4da799d1fd..fa0ac5184c1 100644
--- a/src/bin/pg_basebackup/pg_receivexlog.c
+++ b/src/bin/pg_basebackup/pg_receivexlog.c
@@ -83,10 +83,12 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
timeline);
/*
- * Note that we report the previous, not current, position here. That's
- * the exact location where the timeline switch happend. After the switch,
- * we restart streaming from the beginning of the segment, so xlogpos can
- * smaller than prevpos if we just switched to new timeline.
+ * Note that we report the previous, not current, position here. After a
+ * timeline switch, xlogpos points to the beginning of the segment because
+ * that's where we always begin streaming. Reporting the end of previous
+ * timeline isn't totally accurate, because the next timeline can begin
+ * slightly before the end of the WAL that we received on the previous
+ * timeline, but it's close enough for reporting purposes.
*/
if (prevtimeline != 0 && prevtimeline != timeline)
fprintf(stderr, _("%s: switched to timeline %u at %X/%X\n"),