aboutsummaryrefslogtreecommitdiff
path: root/src/include/access
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-01-18 11:41:36 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-01-18 11:46:49 +0200
commit2ff65553131d8ad2ddbbfe298fffc378f127b15e (patch)
tree4cfbfc70f63e4a440f24b6ee9458c4ebe905cf20 /src/include/access
parent88228e6f1d26619756281c508212498f1de1eff5 (diff)
downloadpostgresql-2ff65553131d8ad2ddbbfe298fffc378f127b15e.tar.gz
postgresql-2ff65553131d8ad2ddbbfe298fffc378f127b15e.zip
Use the right timeline when beginning to stream from master.
The xlogreader refactoring broke the logic to decide which timeline to start streaming from. XLogPageRead() uses the timeline history to check which timeline the requested WAL position falls into. However, after the refactoring, XLogPageRead() is always first called with the first page in the segment, to verify the segment header, and only then with the actual WAL position we're interested in. That first read of the segment's header made XLogPageRead() to always start streaming from the old timeline containing the segment header, not the timeline containing the actual record, if there was a timeline switch within the segment. I thought I fixed this yesterday, but that fix was too narrow and only fixed this for the corner-case that the timeline switch happened in the first page of the segment. To fix this more robustly, pass explicitly the position of the record we're actually interested in to XLogPageRead, and use that to decide which timeline to read from, rather than deduce it from the page and offset. Per report from Fujii Masao.
Diffstat (limited to 'src/include/access')
-rw-r--r--src/include/access/xlogreader.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 36907d6330c..3829ce2ab19 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -27,6 +27,7 @@ typedef struct XLogReaderState XLogReaderState;
typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,
XLogRecPtr targetPagePtr,
int reqLen,
+ XLogRecPtr targetRecPtr,
char *readBuf,
TimeLineID *pageTLI);
@@ -46,11 +47,17 @@ struct XLogReaderState
* -1 on failure. The callback shall sleep, if necessary, to wait for the
* requested bytes to become available. The callback will not be invoked
* again for the same page unless more than the returned number of bytes
- * are necessary.
+ * are needed.
*
- * *pageTLI should be set to the TLI of the file the page was read from.
- * It is currently used only for error reporting purposes, to reconstruct
- * the name of the WAL file where an error occurred.
+ * targetRecPtr is the position of the WAL record we're reading. Usually
+ * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs
+ * to read and verify the page or segment header, before it reads the
+ * actual WAL record it's interested in. In that case, targetRecPtr can
+ * be used to determine which timeline to read the page from.
+ *
+ * The callback shall set *pageTLI to the TLI of the file the page was
+ * read from. It is currently used only for error reporting purposes, to
+ * reconstruct the name of the WAL file where an error occurred.
*/
XLogPageReadCB read_page;
@@ -90,6 +97,9 @@ struct XLogReaderState
XLogRecPtr latestPagePtr;
TimeLineID latestPageTLI;
+ /* beginning of the WAL record being read. */
+ XLogRecPtr currRecPtr;
+
/* Buffer for current ReadRecord result (expandable) */
char *readRecordBuf;
uint32 readRecordBufSize;