Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix regression failure in WAL redo process #152

Merged
merged 4 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions contrib/zenith/inmem_smgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ inmem_nblocks(SMgrRelation reln, ForkNumber forknum)
{
int nblocks = 0;

/*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#0 inmem_nblocks (reln=0x5620695fc048, forknum=VISIBILITYMAP_FORKNUM)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/contrib/zenith/inmem_smgr.c:197
#1 0x000056206894beba in smgrnblocks (reln=0x5620695fc048, forknum=forknum@entry=VISIBILITYMAP_FORKNUM)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/storage/smgr/smgr.c:564
#2 0x00005620686b5aba in vm_extend (rel=rel@entry=0x5620695dcdd8, vm_nblocks=vm_nblocks@entry=1)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/access/heap/visibilitymap.c:650
#3 0x00005620686b5c44 in vm_readbuf (rel=rel@entry=0x5620695dcdd8, blkno=blkno@entry=0, extend=extend@entry=true)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/access/heap/visibilitymap.c:576
#4 0x00005620686b5ea3 in visibilitymap_pin (rel=rel@entry=0x5620695dcdd8, heapBlk=, buf=buf@entry=0x7ffdf3e751f8)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/access/heap/visibilitymap.c:202
#5 0x000056206869dd6a in heap_xlog_insert (record=0x5620695e5928)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/access/heap/heapam.c:8904
#6 0x0000562068956e6d in ApplyRecord (input_message=0x7ffdf3e77270)
at /home/knizhnik/zenith/tmp_install/build/../../vendor/postgres/src/backend/tcop/zenith_wal_redo.c:612

* Find the hightest-numbered page, and report that as the relation size.
* XXX: Why does this get called during WAL replay at all?
*/
for (int i = 0; i < used_pages; i++)
{
if (RelFileNodeEquals(reln->smgr_rnode.node, page_tag[i].rnode)
Expand Down
3 changes: 1 addition & 2 deletions src/backend/access/transam/xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,6 @@ static bool CheckForStandbyTrigger(void);
static void xlog_outrec(StringInfo buf, XLogReaderState *record);
#endif
static void xlog_block_info(StringInfo buf, XLogReaderState *record);
static void xlog_outdesc(StringInfo buf, XLogReaderState *record);
static void pg_start_backup_callback(int code, Datum arg);
static void pg_stop_backup_callback(int code, Datum arg);
static bool read_backup_label(XLogRecPtr *checkPointLoc,
Expand Down Expand Up @@ -10882,7 +10881,7 @@ xlog_block_info(StringInfo buf, XLogReaderState *record)
* Returns a string describing an XLogRecord, consisting of its identity
* optionally followed by a colon, a space, and a further description.
*/
static void
void
xlog_outdesc(StringInfo buf, XLogReaderState *record)
{
RmgrId rmid = XLogRecGetRmid(record);
Expand Down
6 changes: 5 additions & 1 deletion src/backend/storage/buffer/localbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "access/parallel.h"
#include "catalog/catalog.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "utils/guc.h"
Expand Down Expand Up @@ -215,7 +216,10 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);

/* Find smgr relation for buffer */
oreln = smgropen(bufHdr->tag.rnode, MyBackendId, RELPERSISTENCE_TEMP);
if (am_wal_redo_postgres && MyBackendId == InvalidBackendId)
oreln = smgropen(bufHdr->tag.rnode, MyBackendId, RELPERSISTENCE_PERMANENT);
else
oreln = smgropen(bufHdr->tag.rnode, MyBackendId, RELPERSISTENCE_TEMP);

PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);

Expand Down
6 changes: 5 additions & 1 deletion src/backend/storage/smgr/smgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,11 @@ smgropen(RelFileNode rnode, BackendId backend, char relpersistence)
if (reln->smgr_relpersistence == 0)
reln->smgr_relpersistence = relpersistence;
else
Assert(relpersistence == 0 || reln->smgr_relpersistence == relpersistence);
{
if (!(relpersistence == 0 || reln->smgr_relpersistence == relpersistence))
elog(ERROR, "relpersistence mismatch: smgropen %c vs SmgrRelation %c",
relpersistence, reln->smgr_relpersistence);
}
}

return reln;
Expand Down
45 changes: 44 additions & 1 deletion src/backend/tcop/zenith_wal_redo.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static int ReadRedoCommand(StringInfo inBuf);
static void BeginRedoForBlock(StringInfo input_message);
static void PushPage(StringInfo input_message);
static void ApplyRecord(StringInfo input_message);
static void apply_error_callback(void *arg);
static bool redo_block_filter(XLogReaderState *record, uint8 block_id);
static void GetPage(StringInfo input_message);
static ssize_t buffered_read(void *buf, size_t count);
Expand Down Expand Up @@ -579,11 +580,11 @@ PushPage(StringInfo input_message)
static void
ApplyRecord(StringInfo input_message)
{
/* recovery here */
char *errormsg;
XLogRecPtr lsn;
XLogRecord *record;
int nleft;
ErrorContextCallback errcallback;

/*
* message format:
Expand All @@ -601,7 +602,18 @@ ApplyRecord(StringInfo input_message)
elog(ERROR, "mismatch between record (%d) and message size (%d)",
record->xl_tot_len, (int) sizeof(XLogRecord) + nleft);

/* Setup error traceback support for ereport() */
errcallback.callback = apply_error_callback;
errcallback.arg = (void *) reader_state;
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;

XLogBeginRead(reader_state, lsn);
/*
* In lieu of calling XLogReadRecord, store the record 'decoded_record'
* buffer directly.
*/
reader_state->ReadRecPtr = lsn;
reader_state->decoded_record = record;
if (!DecodeXLogRecord(reader_state, record, &errormsg))
elog(ERROR, "failed to decode WAL record: %s", errormsg);
Expand All @@ -613,10 +625,33 @@ ApplyRecord(StringInfo input_message)

redo_read_buffer_filter = NULL;

/* Pop the error context stack */
error_context_stack = errcallback.previous;

elog(TRACE, "applied WAL record with LSN %X/%X",
(uint32) (lsn >> 32), (uint32) lsn);
}

/*
* Error context callback for errors occurring during ApplyRecord
*/
static void
apply_error_callback(void *arg)
{
XLogReaderState *record = (XLogReaderState *) arg;
StringInfoData buf;

initStringInfo(&buf);
xlog_outdesc(&buf, record);

/* translator: %s is a WAL record description */
errcontext("WAL redo at %X/%X for %s",
LSN_FORMAT_ARGS(record->ReadRecPtr),
buf.data);

pfree(buf.data);
}

static bool
redo_block_filter(XLogReaderState *record, uint8 block_id)
{
Expand All @@ -629,6 +664,14 @@ redo_block_filter(XLogReaderState *record, uint8 block_id)
elog(PANIC, "failed to locate backup block with ID %d", block_id);
}

/*
* Can a WAL redo function ever access a relation other than the one that
* it modifies? I don't see why it would.
*/
if (!RelFileNodeEquals(target_tag.rnode, target_redo_tag.rnode))
elog(WARNING, "REDO accessing unexpected page: %u/%u/%u.%u blk %u",
target_tag.rnode.spcNode, target_tag.rnode.dbNode, target_tag.rnode.relNode, target_tag.forkNum, target_tag.blockNum);

/*
* If this block isn't one we are currently restoring, then return 'true'
* so that this gets ignored
Expand Down
1 change: 1 addition & 0 deletions src/include/access/xlog.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ extern void XLogSetReplicationSlotMinimumLSN(XLogRecPtr lsn);
extern void xlog_redo(XLogReaderState *record);
extern void xlog_desc(StringInfo buf, XLogReaderState *record);
extern const char *xlog_identify(uint8 info);
extern void xlog_outdesc(StringInfo buf, XLogReaderState *record);

extern void issue_xlog_fsync(int fd, XLogSegNo segno);

Expand Down