82 char *cur_page,
bool wait_for_wal);
92 elog(elevel,
"page %u of relation %s is uninitialized",
95 elog(elevel,
"page %u of relation %s does not exist",
121 "WAL contains references to invalid pages");
147 key.locator = locator;
187 elog(
DEBUG2,
"page %u of relation %s has been dropped",
220 elog(
DEBUG2,
"page %u of relation %s has been dropped",
249 bool foundone =
false;
269 "WAL contains references to invalid pages");
369 elog(
PANIC,
"failed to locate backup block with ID %d in WAL record",
379 if (willinit && !zeromode)
380 elog(
PANIC,
"block with WILL_INIT flag in WAL record must be zeroed by redo routine");
381 if (!willinit && zeromode)
382 elog(
PANIC,
"block to be initialized in redo routine must be marked with WILL_INIT flag in the WAL record");
394 (
errcode(ERRCODE_INTERNAL_ERROR),
426 if (get_cleanup_lock)
486 buffer = recent_buffer;
487 goto recent_buffer_fast_path;
505 if (blkno < lastblock)
533 recent_buffer_fast_path:
601 rel->
rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
725 Assert(wantLength <= XLOG_BLCKSZ);
737 if (lastReadPage == wantPage &&
738 state->readLen != 0 &&
739 lastReadPage +
state->readLen >= wantPage +
Min(wantLength, XLOG_BLCKSZ - 1))
753 if (
state->currTLI == currTLI && wantPage >= lastReadPage)
765 state->currTLI != currTLI &&
766 state->currTLI != 0 &&
767 ((wantPage + wantLength) /
state->segcxt.ws_segsize) <
768 (
state->currTLIValidUntil /
state->segcxt.ws_segsize))
791 endOfSegment = ((wantPage /
state->segcxt.ws_segsize) + 1) *
792 state->segcxt.ws_segsize - 1;
794 endOfSegment /
state->segcxt.ws_segsize);
805 wantPage + wantLength < state->currTLIValidUntil);
809 elog(
DEBUG3,
"switched to timeline %u valid until %X/%X",
825 if (
state->seg.ws_file >= 0)
831 errmsg(
"requested WAL segment %s has already been removed",
836 errmsg(
"could not open file \"%s\": %m",
846 state->seg.ws_file = -1;
862 int reqLen,
XLogRecPtr targetRecPtr,
char *cur_page)
865 targetRecPtr, cur_page,
true);
878 targetRecPtr, cur_page,
false);
887 char *cur_page,
bool wait_for_wal)
896 loc = targetPagePtr + reqLen;
937 if (
state->currTLI == currTLI)
940 if (loc <= read_upto)
971 read_upto =
state->currTLIValidUntil;
981 tli =
state->currTLI;
988 if (targetPagePtr + XLOG_BLCKSZ <= read_upto)
996 else if (targetPagePtr + reqLen > read_upto)
1004 count = read_upto - targetPagePtr;
1007 if (!
WALRead(
state, cur_page, targetPagePtr, count, tli,
1032 errmsg(
"could not read from WAL segment %s, offset %d: %m",
1039 errmsg(
"could not read from WAL segment %s, offset %d: read %d of %d",
TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history)
XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, TimeLineID *nextTLI)
List * readTimeLineHistory(TimeLineID targetTLI)
Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, BlockNumber extend_to, ReadBufferMode mode)
void ReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBufferForCleanup(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool permanent)
bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, Buffer recent_buffer)
void FlushOneBuffer(Buffer buffer)
static Page BufferGetPage(Buffer buffer)
#define BMR_SMGR(p_smgr, p_relpersistence)
#define BUFFER_LOCK_EXCLUSIVE
@ RBM_ZERO_AND_CLEANUP_LOCK
static bool BufferIsValid(Buffer bufnum)
static bool PageIsNew(Page page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(const char *page)
#define Assert(condition)
void hash_destroy(HTAB *hashp)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
long hash_get_num_entries(HTAB *hashp)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
bool message_level_is_interesting(int elevel)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int BasicOpenFile(const char *fileName, int fileFlags)
void list_free_deep(List *list)
void pfree(void *pointer)
void * palloc0(Size size)
#define CHECK_FOR_INTERRUPTS()
#define ERRCODE_DATA_CORRUPTED
static PgChecksumMode mode
#define INVALID_PROC_NUMBER
#define RelationGetRelationName(relation)
struct RelationData * Relation
#define RelFileLocatorEquals(locator1, locator2)
#define relpathperm(rlocator, forknum)
void pg_usleep(long microsec)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
void smgrdestroyall(void)
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
RelFileLocator rd_locator
bool RecoveryInProgress(void)
XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI)
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
#define LSN_FORMAT_ARGS(lsn)
#define InvalidXLogRecPtr
bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum, Buffer *prefetch_buffer)
bool WALRead(XLogReaderState *state, char *buf, XLogRecPtr startptr, Size count, TimeLineID tli, WALReadError *errinfo)
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
#define XLogRecBlockImageApply(decoder, block_id)
#define XLogRecGetBlock(decoder, i)
#define XLogRecHasBlockImage(decoder, block_id)
#define BKPBLOCK_WILL_INIT
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
void wal_segment_close(XLogReaderState *state)
void FreeFakeRelcacheEntry(Relation fakerel)
void wal_segment_open(XLogReaderState *state, XLogSegNo nextSegNo, TimeLineID *tli_p)
bool ignore_invalid_pages
static void report_invalid_page(int elevel, RelFileLocator locator, ForkNumber forkno, BlockNumber blkno, bool present)
void XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wantLength, TimeLineID currTLI)
FakeRelCacheEntryData * FakeRelCacheEntry
bool XLogHaveInvalidPages(void)
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Buffer XLogReadBufferExtended(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode, Buffer recent_buffer)
void XLogTruncateRelation(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber nblocks)
struct xl_invalid_page xl_invalid_page
Relation CreateFakeRelcacheEntry(RelFileLocator rlocator)
HotStandbyState standbyState
struct xl_invalid_page_key xl_invalid_page_key
int read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *cur_page)
void XLogCheckInvalidPages(void)
static void forget_invalid_pages(RelFileLocator locator, ForkNumber forkno, BlockNumber minblkno)
void WALReadRaiseError(WALReadError *errinfo)
static void log_invalid_page(RelFileLocator locator, ForkNumber forkno, BlockNumber blkno, bool present)
static int read_local_xlog_page_guts(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *cur_page, bool wait_for_wal)
void XLogDropRelation(RelFileLocator rlocator, ForkNumber forknum)
int read_local_xlog_page_no_wait(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *cur_page)
static HTAB * invalid_page_tab
XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState *record, uint8 block_id, ReadBufferMode mode, bool get_cleanup_lock, Buffer *buf)
static void forget_invalid_pages_db(Oid dbid)
void XLogDropDatabase(Oid dbid)