Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3f1ce97

Browse files
committed
Add circular WAL decoding buffer, take II.
Teach xlogreader.c to decode the WAL into a circular buffer. This will support optimizations based on looking ahead, to follow in a later commit. * XLogReadRecord() works as before, decoding records one by one, and allowing them to be examined via the traditional XLogRecGetXXX() macros and certain traditional members like xlogreader->ReadRecPtr. * An alternative new interface XLogReadAhead()/XLogNextRecord() is added that returns pointers to DecodedXLogRecord objects so that it's now possible to look ahead in the WAL stream while replaying. * In order to be able to use the new interface effectively while streaming data, support is added for the page_read() callback to respond to a new nonblocking mode with XLREAD_WOULDBLOCK instead of waiting for more data to arrive. No direct user of the new interface is included in this commit, though XLogReadRecord() uses it internally. Existing code doesn't need to change, except in a few places where it was accessing reader internals directly and now needs to go through accessor macros. Reviewed-by: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Reviewed-by: Andres Freund <andres@anarazel.de> (earlier versions) Discussion: https://postgr.es/m/CA+hUKGJ4VJN8ttxScUFM8dOKX0BrBiboo5uz1cq=AovOddfHpA@mail.gmail.com
1 parent 7a7cd84 commit 3f1ce97

File tree

10 files changed

+686
-174
lines changed

10 files changed

+686
-174
lines changed

src/backend/access/transam/generic_xlog.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,10 @@ generic_redo(XLogReaderState *record)
482482
uint8 block_id;
483483

484484
/* Protect limited size of buffers[] array */
485-
Assert(record->max_block_id < MAX_GENERIC_XLOG_PAGES);
485+
Assert(XLogRecMaxBlockId(record) < MAX_GENERIC_XLOG_PAGES);
486486

487487
/* Iterate over blocks */
488-
for (block_id = 0; block_id <= record->max_block_id; block_id++)
488+
for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
489489
{
490490
XLogRedoAction action;
491491

@@ -525,7 +525,7 @@ generic_redo(XLogReaderState *record)
525525
}
526526

527527
/* Changes are done: unlock and release all buffers */
528-
for (block_id = 0; block_id <= record->max_block_id; block_id++)
528+
for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
529529
{
530530
if (BufferIsValid(buffers[block_id]))
531531
UnlockReleaseBuffer(buffers[block_id]);

src/backend/access/transam/xlog.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,8 @@ XLogInsertRecord(XLogRecData *rdata,
971971
if (XLOG_DEBUG)
972972
{
973973
static XLogReaderState *debug_reader = NULL;
974+
XLogRecord *record;
975+
DecodedXLogRecord *decoded;
974976
StringInfoData buf;
975977
StringInfoData recordBuf;
976978
char *errormsg = NULL;
@@ -990,6 +992,11 @@ XLogInsertRecord(XLogRecData *rdata,
990992
for (; rdata != NULL; rdata = rdata->next)
991993
appendBinaryStringInfo(&recordBuf, rdata->data, rdata->len);
992994

995+
/* We also need temporary space to decode the record. */
996+
record = (XLogRecord *) recordBuf.data;
997+
decoded = (DecodedXLogRecord *)
998+
palloc(DecodeXLogRecordRequiredSpace(record->xl_tot_len));
999+
9931000
if (!debug_reader)
9941001
debug_reader = XLogReaderAllocate(wal_segment_size, NULL,
9951002
XL_ROUTINE(), NULL);
@@ -998,7 +1005,10 @@ XLogInsertRecord(XLogRecData *rdata,
9981005
{
9991006
appendStringInfoString(&buf, "error decoding record: out of memory while allocating a WAL reading processor");
10001007
}
1001-
else if (!DecodeXLogRecord(debug_reader, (XLogRecord *) recordBuf.data,
1008+
else if (!DecodeXLogRecord(debug_reader,
1009+
decoded,
1010+
record,
1011+
EndPos,
10021012
&errormsg))
10031013
{
10041014
appendStringInfo(&buf, "error decoding record: %s",
@@ -1007,10 +1017,14 @@ XLogInsertRecord(XLogRecData *rdata,
10071017
else
10081018
{
10091019
appendStringInfoString(&buf, " - ");
1020+
1021+
debug_reader->record = decoded;
10101022
xlog_outdesc(&buf, debug_reader);
1023+
debug_reader->record = NULL;
10111024
}
10121025
elog(LOG, "%s", buf.data);
10131026

1027+
pfree(decoded);
10141028
pfree(buf.data);
10151029
pfree(recordBuf.data);
10161030
MemoryContextSwitchTo(oldCxt);
@@ -7738,7 +7752,7 @@ xlog_redo(XLogReaderState *record)
77387752
* resource manager needs to generate conflicts, it has to define a
77397753
* separate WAL record type and redo routine.
77407754
*/
7741-
for (uint8 block_id = 0; block_id <= record->max_block_id; block_id++)
7755+
for (uint8 block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
77427756
{
77437757
Buffer buffer;
77447758

0 commit comments

Comments
 (0)