Skip to content

Commit ac97776

Browse files
author
Antonin Houska
committed
Fixed handling of special values of xl_rmid.
In some cases we forgot that special value of block id (XLR_BLOCK_ID_DATA_SHORT / XLR_BLOCK_ID_DATA_LONG) precedes the actual record data. Thus RelFileNode was read from incorrect position and filtering based on that didn't work well.
1 parent 4cc27e9 commit ac97776

File tree

1 file changed

+75
-28
lines changed

1 file changed

+75
-28
lines changed

src/wbfilter.c

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -177,29 +177,6 @@ WbFProcessWalDataBlock(ReplMessage* msg, FilterData* fl, XLogRecPtr *retryPos)
177177
parse_debug(" - Xlog switch, copying %d bytes ", fl->dataNeeded);
178178
break;
179179
}
180-
else if (rec->xl_rmid == RM_SMGR_ID && (rec->xl_info & 0xF0) == XLOG_SMGR_CREATE)
181-
{
182-
fl->state = FS_BUFFER_FILENODE;
183-
fl->dataNeeded = sizeof(RelFileNode);
184-
parse_debug(" - SMGR record, buffering %d bytes for filenode", fl->dataNeeded);
185-
break;
186-
}
187-
else if (rec->xl_rmid == RM_SMGR_ID && (rec->xl_info & 0xF0) == XLOG_SMGR_TRUNCATE)
188-
{
189-
fl->state = FS_BUFFER_FILENODE;
190-
// Here we rely on the fact that FS_BUFFER_FILENODE will ignore any extra data
191-
fl->recordRemaining -= sizeof(BlockNumber);
192-
fl->dataNeeded = sizeof(BlockNumber) + sizeof(RelFileNode);
193-
parse_debug(" - SMGR record, buffering %d bytes for filenode", fl->dataNeeded);
194-
break;
195-
}
196-
else if (rec->xl_rmid == RM_SEQ_ID && (rec->xl_info & 0xF0) == XLOG_SEQ_LOG)
197-
{
198-
fl->state = FS_BUFFER_FILENODE;
199-
fl->dataNeeded = sizeof(RelFileNode);
200-
parse_debug(" - SMGR record, buffering %d bytes for filenode", fl->dataNeeded);
201-
break;
202-
}
203180
else if (fl->recordRemaining == 0)
204181
{
205182
fl->state = FS_COPY_NORMAL;
@@ -228,10 +205,79 @@ WbFProcessWalDataBlock(ReplMessage* msg, FilterData* fl, XLogRecPtr *retryPos)
228205

229206
if (block_id > XLR_MAX_BLOCK_ID)
230207
{
231-
fl->state = FS_COPY_NORMAL;
232-
fl->dataNeeded = fl->recordRemaining;
233-
FilterClearBuffer(fl);
234-
parse_debug(" - No block references in record, copying %d bytes ", fl->dataNeeded);
208+
XLogRecord *rec = (XLogRecord*) fl->buffer;
209+
210+
if (rec->xl_rmid == RM_SMGR_ID &&
211+
(rec->xl_info & 0xF0) == XLOG_SMGR_CREATE)
212+
{
213+
/* SMGR record should not be longer than 255 bytes. */
214+
Assert(block_id == XLR_BLOCK_ID_DATA_SHORT);
215+
216+
fl->state = FS_BUFFER_FILENODE;
217+
/* Include the data length info. */
218+
fl->dataNeeded = sizeof(uint8) + sizeof(RelFileNode);
219+
fl->recordRemaining -= sizeof(uint8);
220+
parse_debug(" - SMGR record, buffering %d bytes for filenode",
221+
fl->dataNeeded);
222+
break;
223+
}
224+
else if (rec->xl_rmid == RM_SMGR_ID &&
225+
(rec->xl_info & 0xF0) == XLOG_SMGR_TRUNCATE)
226+
{
227+
/* SMGR record should not be longer than 255 bytes. */
228+
Assert(block_id == XLR_BLOCK_ID_DATA_SHORT);
229+
230+
fl->state = FS_BUFFER_FILENODE;
231+
// Here we rely on the fact that FS_BUFFER_FILENODE will ignore any extra data
232+
/* Include the data length info. */
233+
fl->dataNeeded = sizeof(uint8) + sizeof(BlockNumber) +
234+
sizeof(RelFileNode);
235+
fl->recordRemaining -= sizeof(uint8) + sizeof(BlockNumber);
236+
parse_debug(" - SMGR record, buffering %d bytes for filenode",
237+
fl->dataNeeded);
238+
break;
239+
}
240+
/*
241+
* XXX The following seems to be dead code since PG
242+
* calls XLogRegisterBuffer() before it inserts the
243+
* XLOG_SEQ_LOG record. Thus the RelFileNode is
244+
* located after XLogRecordBlockHeader, so we can do
245+
* our filtering without checking the actual record.
246+
*/
247+
else if (rec->xl_rmid == RM_SEQ_ID &&
248+
(rec->xl_info & 0xF0) == XLOG_SEQ_LOG)
249+
{
250+
fl->state = FS_BUFFER_FILENODE;
251+
fl->dataNeeded = sizeof(RelFileNode);
252+
253+
/*
254+
* Make sure we skip the whole "block id" and the
255+
* size info.
256+
*/
257+
if (block_id == XLR_BLOCK_ID_DATA_SHORT)
258+
{
259+
fl->dataNeeded += sizeof(uint8);
260+
fl->recordRemaining -= sizeof(uint8);
261+
}
262+
else if (block_id == XLR_BLOCK_ID_DATA_LONG)
263+
{
264+
fl->dataNeeded += sizeof(uint32);
265+
fl->recordRemaining -= sizeof(uint32);
266+
}
267+
else
268+
Assert(false);
269+
270+
parse_debug(" - SMGR record, buffering %d bytes for filenode",
271+
fl->dataNeeded);
272+
break;
273+
}
274+
else
275+
{
276+
fl->state = FS_COPY_NORMAL;
277+
fl->dataNeeded = fl->recordRemaining;
278+
FilterClearBuffer(fl);
279+
parse_debug(" - No block references in record, copying %d bytes ", fl->dataNeeded);
280+
}
235281
}
236282
else
237283
{
@@ -557,7 +603,8 @@ OidInZeroTermOidList(Oid search, Oid *list)
557603
static bool
558604
NeedToFilter(FilterData *fl, RelFileNode *node)
559605
{
560-
log_debug2("Checking relfilnode with dbNode %d, spcNode %d", node->dbNode, node->spcNode);
606+
log_debug2("Checking relfilnode [relNode, dbNode, spcNode] = [%u, %u, %u]",
607+
node->relNode, node->dbNode, node->spcNode);
561608
if (fl->include_tablespaces)
562609
if (!OidInZeroTermOidList(node->spcNode, fl->include_tablespaces))
563610
{

0 commit comments

Comments
 (0)