diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index ce2a3e421462..a228b0ed2749 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -876,6 +876,7 @@ read_local_xlog_page_guts(XLogReaderState *state, XLogRecPtr targetPagePtr, int count; WALReadError errinfo; TimeLineID currTLI; + Size bytesRead; loc = targetPagePtr + reqLen; @@ -995,9 +996,25 @@ read_local_xlog_page_guts(XLogReaderState *state, XLogRecPtr targetPagePtr, count = read_upto - targetPagePtr; } - if (!WALRead(state, cur_page, targetPagePtr, count, tli, - &errinfo)) - WALReadRaiseError(&errinfo); + /* First attempt to read from WAL buffers */ + bytesRead = WALReadFromBuffers(cur_page, targetPagePtr, count, currTLI); + + /* If we still have bytes to read, get them from WAL file */ + if (bytesRead < count) + { + if (!WALRead(state, + cur_page + bytesRead, + targetPagePtr + bytesRead, + count - bytesRead, + tli, + &errinfo)) + { + WALReadRaiseError(&errinfo); + } + bytesRead = count; /* All requested bytes read */ + } + + Assert(bytesRead == count); /* number of valid bytes in the buffer */ return count; diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index a1b4301a4ee2..01b8d6b673ac 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1050,6 +1050,7 @@ logical_read_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int req WALReadError errinfo; XLogSegNo segno; TimeLineID currTLI; + Size bytesRead; /* * Make sure we have enough WAL available before retrieving the current @@ -1087,16 +1088,29 @@ logical_read_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int req else count = flushptr - targetPagePtr; /* part of the page available */ - /* now actually read the data, we know it's there */ - if (!WALRead(state, - cur_page, - targetPagePtr, - count, - currTLI, /* Pass the current TLI because only + /* First attempt to read from WAL buffers */ + bytesRead = WALReadFromBuffers(cur_page, targetPagePtr, count, currTLI); + + targetPagePtr += bytesRead; + + /* If we still have bytes to read, get them from WAL file */ + if (bytesRead < count) + { + if (!WALRead(state, + cur_page + bytesRead, + targetPagePtr, + count - bytesRead, + currTLI, /* Pass the current TLI because only * WalSndSegmentOpen controls whether new TLI * is needed. */ - &errinfo)) - WALReadRaiseError(&errinfo); + &errinfo)) + { + WALReadRaiseError(&errinfo); + } + bytesRead = count; /* All requested bytes read */ + } + + Assert(bytesRead == count); /* * After reading into the buffer, check that what we read was valid. We do @@ -3190,7 +3204,7 @@ XLogSendPhysical(void) Size nbytes; XLogSegNo segno; WALReadError errinfo; - Size rbytes; + Size bytesRead; /* If requested switch the WAL sender to the stopping state. */ if (got_STOPPING) @@ -3406,24 +3420,33 @@ XLogSendPhysical(void) enlargeStringInfo(&output_message, nbytes); retry: - /* attempt to read WAL from WAL buffers first */ - rbytes = WALReadFromBuffers(&output_message.data[output_message.len], - startptr, nbytes, xlogreader->seg.ws_tli); - output_message.len += rbytes; - startptr += rbytes; - nbytes -= rbytes; - - /* now read the remaining WAL from WAL file */ - if (nbytes > 0 && - !WALRead(xlogreader, - &output_message.data[output_message.len], - startptr, - nbytes, - xlogreader->seg.ws_tli, /* Pass the current TLI because - * only WalSndSegmentOpen controls - * whether new TLI is needed. */ - &errinfo)) - WALReadRaiseError(&errinfo); + /* First attempt to read from WAL buffers */ + bytesRead = WALReadFromBuffers(&output_message.data[output_message.len], + startptr, + nbytes, + xlogreader->seg.ws_tli); + + startptr += bytesRead; + + /* If we still have bytes to read, get them from WAL file */ + if (bytesRead < nbytes) + { + if (!WALRead(xlogreader, + &output_message.data[output_message.len + bytesRead], + startptr, + nbytes - bytesRead, + xlogreader->seg.ws_tli, /* Pass the current TLI + * because only + * WalSndSegmentOpen controls + * whether new TLI is needed. */ + &errinfo)) + { + WALReadRaiseError(&errinfo); + } + bytesRead = nbytes; /* All requested bytes read */ + } + + Assert(bytesRead == nbytes); /* See logical_read_xlog_page(). */ XLByteToSeg(startptr, segno, xlogreader->segcxt.ws_segsize);