85 char *cur_page,
bool wait_for_wal);
95 elog(elevel,
"page %u of relation %s is uninitialized",
98 elog(elevel,
"page %u of relation %s does not exist",
124 "WAL contains references to invalid pages");
150 key.locator = locator;
190 elog(
DEBUG2,
"page %u of relation %s has been dropped",
223 elog(
DEBUG2,
"page %u of relation %s has been dropped",
252 bool foundone =
false;
272 "WAL contains references to invalid pages");
372 elog(
PANIC,
"failed to locate backup block with ID %d in WAL record",
382 if (willinit && !zeromode)
383 elog(
PANIC,
"block with WILL_INIT flag in WAL record must be zeroed by redo routine");
384 if (!willinit && zeromode)
385 elog(
PANIC,
"block to be initialized in redo routine must be marked with WILL_INIT flag in the WAL record");
397 (
errcode(ERRCODE_INTERNAL_ERROR),
429 if (get_cleanup_lock)
489 buffer = recent_buffer;
490 goto recent_buffer_fast_path;
508 if (blkno < lastblock)
536 recent_buffer_fast_path:
604 rel->
rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
727 Assert(wantLength <= XLOG_BLCKSZ);
739 if (lastReadPage == wantPage &&
740 state->readLen != 0 &&
741 lastReadPage +
state->readLen >= wantPage +
Min(wantLength, XLOG_BLCKSZ - 1))
755 if (
state->currTLI == currTLI && wantPage >= lastReadPage)
767 state->currTLI != currTLI &&
768 state->currTLI != 0 &&
769 ((wantPage + wantLength) /
state->segcxt.ws_segsize) <
770 (
state->currTLIValidUntil /
state->segcxt.ws_segsize))
793 endOfSegment = ((wantPage /
state->segcxt.ws_segsize) + 1) *
794 state->segcxt.ws_segsize - 1;
796 endOfSegment /
state->segcxt.ws_segsize);
807 wantPage + wantLength < state->currTLIValidUntil);
811 elog(
DEBUG3,
"switched to timeline %u valid until %X/%X",
827 if (
state->seg.ws_file >= 0)
833 errmsg(
"requested WAL segment %s has already been removed",
838 errmsg(
"could not open file \"%s\": %m",
848 state->seg.ws_file = -1;
864 int reqLen,
XLogRecPtr targetRecPtr,
char *cur_page)
867 targetRecPtr, cur_page,
true);
880 targetRecPtr, cur_page,
false);
889 char *cur_page,
bool wait_for_wal)
898 loc = targetPagePtr + reqLen;
939 if (
state->currTLI == currTLI)
942 if (loc <= read_upto)
973 read_upto =
state->currTLIValidUntil;
983 tli =
state->currTLI;
990 if (targetPagePtr + XLOG_BLCKSZ <= read_upto)
998 else if (targetPagePtr + reqLen > read_upto)
1006 count = read_upto - targetPagePtr;
1014 if (!
WALRead(
state, cur_page, targetPagePtr, XLOG_BLCKSZ, tli,
1039 errmsg(
"could not read from WAL segment %s, offset %d: %m",
1046 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(Page page)
elog(ERROR, "%s: %s", p2, msg)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
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 RelationGetRelationName(relation)
struct RelationData * Relation
#define RelFileLocatorEquals(locator1, locator2)
#define relpathperm(rlocator, forknum)
void pg_usleep(long microsec)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
SMgrRelation smgropen(RelFileLocator rlocator, BackendId backend)
void smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
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)