PostgreSQL Source Code: src/backend/access/transam/xlogreader.c File Reference (original) (raw)

Go to the source code of this file.

Macros
#define MAX_ERRORMSG_LEN 1000
#define DEFAULT_DECODE_BUFFER_SIZE (64 * 1024)
#define COPY_HEADER_FIELD(_dst, _size)
Functions
static void report_invalid_record (XLogReaderState *state, const char *fmt,...) pg_attribute_printf(2
static void static void allocate_recordbuf (XLogReaderState *state, uint32 reclength)
static int ReadPageInternal (XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
static void XLogReaderInvalReadState (XLogReaderState *state)
static XLogPageReadResult XLogDecodeNextRecord (XLogReaderState *state, bool nonblocking)
static bool ValidXLogRecordHeader (XLogReaderState *state, XLogRecPtr RecPtr, XLogRecPtr PrevRecPtr, XLogRecord *record, bool randAccess)
static bool ValidXLogRecord (XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
static void ResetDecoder (XLogReaderState *state)
static void WALOpenSegmentInit (WALOpenSegment *seg, WALSegmentContext *segcxt, int segsize, const char *waldir)
void XLogReaderSetDecodeBuffer (XLogReaderState *state, void *buffer, size_t size)
XLogReaderState * XLogReaderAllocate (int wal_segment_size, const char *waldir, XLogReaderRoutine *routine, void *private_data)
void XLogReaderFree (XLogReaderState *state)
void XLogBeginRead (XLogReaderState *state, XLogRecPtr RecPtr)
XLogRecPtr XLogReleasePreviousRecord (XLogReaderState *state)
DecodedXLogRecord * XLogNextRecord (XLogReaderState *state, char **errormsg)
XLogRecord * XLogReadRecord (XLogReaderState *state, char **errormsg)
static DecodedXLogRecord * XLogReadRecordAlloc (XLogReaderState *state, size_t xl_tot_len, bool allow_oversized)
DecodedXLogRecord * XLogReadAhead (XLogReaderState *state, bool nonblocking)
bool XLogReaderValidatePageHeader (XLogReaderState *state, XLogRecPtr recptr, char *phdr)
void XLogReaderResetError (XLogReaderState *state)
XLogRecPtr XLogFindNextRecord (XLogReaderState *state, XLogRecPtr RecPtr)
bool WALRead (XLogReaderState *state, char *buf, XLogRecPtr startptr, Size count, TimeLineID tli, WALReadError *errinfo)
size_t DecodeXLogRecordRequiredSpace (size_t xl_tot_len)
bool DecodeXLogRecord (XLogReaderState *state, DecodedXLogRecord *decoded, XLogRecord *record, XLogRecPtr lsn, char **errormsg)
void XLogRecGetBlockTag (XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
bool XLogRecGetBlockTagExtended (XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum, Buffer *prefetch_buffer)
char * XLogRecGetBlockData (XLogReaderState *record, uint8 block_id, Size *len)
bool RestoreBlockImage (XLogReaderState *record, uint8 block_id, char *page)
FullTransactionId XLogRecGetFullXid (XLogReaderState *record)

COPY_HEADER_FIELD

| #define COPY_HEADER_FIELD | ( | | _dst, | | --------------------------- | - | | ------ | | | _size | | | | | ) | | | |

Value:

do { \

goto shortdata_err; \

memcpy(_dst, ptr, _size); \

ptr += _size; \

remaining -= _size; \

} while(0)

DEFAULT_DECODE_BUFFER_SIZE

#define DEFAULT_DECODE_BUFFER_SIZE (64 * 1024)

MAX_ERRORMSG_LEN

#define MAX_ERRORMSG_LEN 1000

allocate_recordbuf()

DecodeXLogRecord()

Definition at line 1672 of file xlogreader.c.

1677{

1678

1679

1680

1681#define COPY_HEADER_FIELD(_dst, _size) \

1682 do { \

1683 if (remaining < _size) \

1684 goto shortdata_err; \

1685 memcpy(_dst, ptr, _size); \

1686 ptr += _size; \

1687 remaining -= _size; \

1688 } while(0)

1689

1690 char *ptr;

1691 char *out;

1696

1697 decoded->header = *record;

1698 decoded->lsn = lsn;

1699 decoded->next = NULL;

1705 ptr = (char *) record;

1708

1709

1710 datatotal = 0;

1712 {

1714

1716 {

1717

1718 uint8 main_data_len;

1719

1721

1723 datatotal += main_data_len;

1724 break;

1725

1726 }

1728 {

1729

1730 uint32 main_data_len;

1731

1734 datatotal += main_data_len;

1735 break;

1736

1737 }

1739 {

1741 }

1743 {

1745 }

1747 {

1748

1750 uint8 fork_flags;

1751

1752

1753 for (int i = decoded->max_block_id + 1; i < block_id; ++i)

1755

1756 if (block_id <= decoded->max_block_id)

1757 {

1759 "out-of-order block_id %u at %X/%X",

1760 block_id,

1762 goto err;

1763 }

1765

1766 blk = &decoded->blocks[block_id];

1769

1772 blk->flags = fork_flags;

1775

1777

1779

1781 {

1783 "BKPBLOCK_HAS_DATA set, but no data included at %X/%X",

1785 goto err;

1786 }

1788 {

1790 "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X",

1791 (unsigned int) blk->data_len,

1793 goto err;

1794 }

1796

1798 {

1802

1804

1806 {

1809 else

1811 }

1812 else

1815

1816

1817

1818

1819

1824 {

1826 "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X",

1829 (unsigned int) blk->bimg_len,

1831 goto err;

1832 }

1833

1834

1835

1836

1837

1840 {

1842 "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X",

1846 goto err;

1847 }

1848

1849

1850

1851

1854 {

1856 "BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X",

1857 (unsigned int) blk->bimg_len,

1859 goto err;

1860 }

1861

1862

1863

1864

1865

1869 {

1871 "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %u at %X/%X",

1872 (unsigned int) blk->data_len,

1874 goto err;

1875 }

1876 }

1878 {

1881 }

1882 else

1883 {

1884 if (rlocator == NULL)

1885 {

1887 "BKPBLOCK_SAME_REL set but no previous rel at %X/%X",

1889 goto err;

1890 }

1891

1893 }

1895 }

1896 else

1897 {

1899 "invalid block_id %u at %X/%X",

1901 goto err;

1902 }

1903 }

1904

1906 goto shortdata_err;

1907

1908

1909

1910

1911

1912

1913

1914

1915 out = ((char *) decoded) +

1918

1919

1920 for (block_id = 0; block_id <= decoded->max_block_id; block_id++)

1921 {

1923

1925 continue;

1926

1928

1930 {

1931

1933 memcpy(out, ptr, blk->bimg_len);

1936 }

1938 {

1939 out = (char *) MAXALIGN(out);

1940 blk->data = out;

1944 }

1945 }

1946

1947

1949 {

1950 out = (char *) MAXALIGN(out);

1955 }

1956

1957

1958 decoded->size = MAXALIGN(out - (char *) decoded);

1960 decoded->size);

1961

1962 return true;

1963

1964shortdata_err:

1966 "record with invalid length at %X/%X",

1969 *errormsg = state->errormsg_buf;

1970

1971 return false;

1972}

void err(int eval, const char *fmt,...)

Assert(PointerIsAligned(start, uint64))

#define InvalidRepOriginId

struct DecodedXLogRecord * next

TransactionId toplevel_xid

RepOriginId record_origin

DecodedBkpBlock blocks[FLEXIBLE_ARRAY_MEMBER]

#define InvalidTransactionId

#define LSN_FORMAT_ARGS(lsn)

static void report_invalid_record(XLogReaderState *state, const char *fmt,...) pg_attribute_printf(2

#define COPY_HEADER_FIELD(_dst, _size)

size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len)

#define BKPBLOCK_FORK_MASK

#define BKPBLOCK_HAS_DATA

#define BKPIMAGE_HAS_HOLE

#define XLR_BLOCK_ID_DATA_LONG

#define BKPIMAGE_COMPRESSED(info)

#define XLR_BLOCK_ID_TOPLEVEL_XID

#define XLR_BLOCK_ID_DATA_SHORT

#define BKPBLOCK_SAME_REL

#define XLR_BLOCK_ID_ORIGIN

#define BKPBLOCK_HAS_IMAGE

References DecodedBkpBlock::apply_image, Assert(), DecodedBkpBlock::bimg_info, DecodedBkpBlock::bimg_len, DecodedBkpBlock::bkp_image, BKPBLOCK_FORK_MASK, BKPBLOCK_HAS_DATA, BKPBLOCK_HAS_IMAGE, BKPBLOCK_SAME_REL, BKPIMAGE_APPLY, BKPIMAGE_COMPRESSED, BKPIMAGE_HAS_HOLE, DecodedBkpBlock::blkno, DecodedXLogRecord::blocks, COPY_HEADER_FIELD, DecodedBkpBlock::data, DecodedBkpBlock::data_len, DecodeXLogRecordRequiredSpace(), err(), DecodedBkpBlock::flags, DecodedBkpBlock::forknum, DecodedBkpBlock::has_data, DecodedBkpBlock::has_image, DecodedXLogRecord::header, DecodedBkpBlock::hole_length, DecodedBkpBlock::hole_offset, i, DecodedBkpBlock::in_use, InvalidBuffer, InvalidRepOriginId, InvalidTransactionId, DecodedXLogRecord::lsn, LSN_FORMAT_ARGS, DecodedXLogRecord::main_data, DecodedXLogRecord::main_data_len, DecodedXLogRecord::max_block_id, MAXALIGN, DecodedXLogRecord::next, DecodedBkpBlock::prefetch_buffer, DecodedXLogRecord::record_origin, remaining, report_invalid_record(), DecodedBkpBlock::rlocator, DecodedXLogRecord::size, SizeOfXLogRecord, DecodedXLogRecord::toplevel_xid, XLogRecord::xl_tot_len, XLR_BLOCK_ID_DATA_LONG, XLR_BLOCK_ID_DATA_SHORT, XLR_BLOCK_ID_ORIGIN, XLR_BLOCK_ID_TOPLEVEL_XID, and XLR_MAX_BLOCK_ID.

Referenced by XLogDecodeNextRecord(), and XLogInsertRecord().

DecodeXLogRecordRequiredSpace()

size_t DecodeXLogRecordRequiredSpace ( size_t xl_tot_len )

ReadPageInternal()

Definition at line 1001 of file xlogreader.c.

1002{

1004 uint32 targetPageOff;

1007

1008 Assert((pageptr % XLOG_BLCKSZ) == 0);

1009

1010 XLByteToSeg(pageptr, targetSegNo, state->segcxt.ws_segsize);

1012

1013

1014 if (targetSegNo == state->seg.ws_segno &&

1015 targetPageOff == state->segoff && reqLen <= state->readLen)

1016 return state->readLen;

1017

1018

1019

1020

1021

1022

1023 state->readLen = 0;

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037 if (targetSegNo != state->seg.ws_segno && targetPageOff != 0)

1038 {

1039 XLogRecPtr targetSegmentPtr = pageptr - targetPageOff;

1040

1041 readLen = state->routine.page_read(state, targetSegmentPtr, XLOG_BLCKSZ,

1042 state->currRecPtr,

1043 state->readBuf);

1047 goto err;

1048

1049

1051

1053 state->readBuf))

1054 goto err;

1055 }

1056

1057

1058

1059

1060

1062 state->currRecPtr,

1063 state->readBuf);

1067 goto err;

1068

1070

1071

1073 goto err;

1074

1076

1078

1079

1081 {

1083 state->currRecPtr,

1084 state->readBuf);

1088 goto err;

1089 }

1090

1091

1092

1093

1095 goto err;

1096

1097

1098 state->seg.ws_segno = targetSegNo;

1099 state->segoff = targetPageOff;

1101

1103

1106

1108}

if(TABLE==NULL||TABLE_index==NULL)

#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)

XLogPageHeaderData * XLogPageHeader

#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

#define SizeOfXLogShortPHD

#define XLogPageHeaderSize(hdr)

static void XLogReaderInvalReadState(XLogReaderState *state)

bool XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, char *phdr)

References Assert(), err(), if(), Max, readLen, SizeOfXLogShortPHD, XLByteToSeg, XLogPageHeaderSize, XLogReaderInvalReadState(), XLogReaderValidatePageHeader(), XLogSegmentOffset, XLREAD_FAIL, and XLREAD_WOULDBLOCK.

Referenced by XLogDecodeNextRecord(), and XLogFindNextRecord().

report_invalid_record()

static void report_invalid_record ( XLogReaderState * state, const char * fmt, ... ) static

ResetDecoder()

RestoreBlockImage()

Definition at line 2066 of file xlogreader.c.

2067{

2069 char *ptr;

2071

2074 {

2076 "could not restore image at %X/%X with invalid block %d specified",

2078 block_id);

2079 return false;

2080 }

2082 {

2083 report_invalid_record(record, "could not restore image at %X/%X with invalid state, block %d",

2085 block_id);

2086 return false;

2087 }

2088

2091

2093 {

2094

2095 bool decomp_success = true;

2096

2098 {

2101 decomp_success = false;

2102 }

2104 {

2105#ifdef USE_LZ4

2106 if (LZ4_decompress_safe(ptr, tmp.data,

2108 decomp_success = false;

2109#else

2110 report_invalid_record(record, "could not restore image at %X/%X compressed with %s not supported by build, block %d",

2112 "LZ4",

2113 block_id);

2114 return false;

2115#endif

2116 }

2118 {

2119#ifdef USE_ZSTD

2120 size_t decomp_result = ZSTD_decompress(tmp.data,

2123

2124 if (ZSTD_isError(decomp_result))

2125 decomp_success = false;

2126#else

2127 report_invalid_record(record, "could not restore image at %X/%X compressed with %s not supported by build, block %d",

2129 "zstd",

2130 block_id);

2131 return false;

2132#endif

2133 }

2134 else

2135 {

2136 report_invalid_record(record, "could not restore image at %X/%X compressed with unknown method, block %d",

2138 block_id);

2139 return false;

2140 }

2141

2142 if (!decomp_success)

2143 {

2146 block_id);

2147 return false;

2148 }

2149

2150 ptr = tmp.data;

2151 }

2152

2153

2155 {

2156 memcpy(page, ptr, BLCKSZ);

2157 }

2158 else

2159 {

2161

2166 }

2167

2168 return true;

2169}

#define MemSet(start, val, len)

int32 pglz_decompress(const char *source, int32 slen, char *dest, int32 rawsize, bool check_complete)

DecodedXLogRecord * record

#define BKPIMAGE_COMPRESS_ZSTD

#define BKPIMAGE_COMPRESS_LZ4

#define BKPIMAGE_COMPRESS_PGLZ

References DecodedBkpBlock::bimg_info, DecodedBkpBlock::bimg_len, DecodedBkpBlock::bkp_image, BKPIMAGE_COMPRESS_LZ4, BKPIMAGE_COMPRESS_PGLZ, BKPIMAGE_COMPRESS_ZSTD, BKPIMAGE_COMPRESSED, DecodedXLogRecord::blocks, PGAlignedBlock::data, DecodedBkpBlock::has_image, DecodedBkpBlock::hole_length, DecodedBkpBlock::hole_offset, DecodedBkpBlock::in_use, LSN_FORMAT_ARGS, DecodedXLogRecord::max_block_id, MemSet, pglz_decompress(), XLogReaderState::ReadRecPtr, XLogReaderState::record, and report_invalid_record().

Referenced by GetWALBlockInfo(), verifyBackupPageConsistency(), XLogReadBufferForRedoExtended(), and XLogRecordSaveFPWs().

ValidXLogRecord()

Definition at line 1194 of file xlogreader.c.

1195{

1197

1199

1200

1203

1206

1208 {

1210 "incorrect resource manager data checksum in record at %X/%X",

1212 return false;

1213 }

1214

1215 return true;

1216}

#define COMP_CRC32C(crc, data, len)

#define EQ_CRC32C(c1, c2)

References Assert(), COMP_CRC32C, crc, EQ_CRC32C, FIN_CRC32C, INIT_CRC32C, LSN_FORMAT_ARGS, report_invalid_record(), SizeOfXLogRecord, XLogRecord::xl_crc, and XLogRecord::xl_tot_len.

Referenced by XLogDecodeNextRecord().

ValidXLogRecordHeader()

Definition at line 1128 of file xlogreader.c.

1131{

1133 {

1135 "invalid record length at %X/%X: expected at least %u, got %u",

1138 return false;

1139 }

1141 {

1143 "invalid resource manager ID %u at %X/%X",

1145 return false;

1146 }

1147 if (randAccess)

1148 {

1149

1150

1151

1152

1153 if (!(record->xl_prev < RecPtr))

1154 {

1156 "record with incorrect prev-link %X/%X at %X/%X",

1159 return false;

1160 }

1161 }

1162 else

1163 {

1164

1165

1166

1167

1168

1169 if (record->xl_prev != PrevRecPtr)

1170 {

1172 "record with incorrect prev-link %X/%X at %X/%X",

1175 return false;

1176 }

1177 }

1178

1179 return true;

1180}

#define RmgrIdIsValid(rmid)

References LSN_FORMAT_ARGS, report_invalid_record(), RmgrIdIsValid, SizeOfXLogRecord, XLogRecord::xl_prev, XLogRecord::xl_rmid, and XLogRecord::xl_tot_len.

Referenced by XLogDecodeNextRecord().

WALOpenSegmentInit()

WALRead()

Definition at line 1504 of file xlogreader.c.

1507{

1508 char *p;

1510 Size nbytes;

1511#ifndef FRONTEND

1513#endif

1514

1515 p = buf;

1516 recptr = startptr;

1517 nbytes = count;

1518

1519 while (nbytes > 0)

1520 {

1522 int segbytes;

1523 int readbytes;

1524

1526

1527

1528

1529

1530

1531

1532 if (state->seg.ws_file < 0 ||

1534 tli != state->seg.ws_tli)

1535 {

1537

1538 if (state->seg.ws_file >= 0)

1539 state->routine.segment_close(state);

1540

1542 state->routine.segment_open(state, nextSegNo, &tli);

1543

1544

1546

1547

1548 state->seg.ws_tli = tli;

1549 state->seg.ws_segno = nextSegNo;

1550 }

1551

1552

1553 if (nbytes > (state->segcxt.ws_segsize - startoff))

1554 segbytes = state->segcxt.ws_segsize - startoff;

1555 else

1556 segbytes = nbytes;

1557

1558#ifndef FRONTEND

1559

1561

1563#endif

1564

1565

1566 errno = 0;

1567 readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);

1568

1569#ifndef FRONTEND

1571

1573 io_start, 1, readbytes);

1574#endif

1575

1576 if (readbytes <= 0)

1577 {

1579 errinfo->wre_req = segbytes;

1580 errinfo->wre_read = readbytes;

1581 errinfo->wre_off = startoff;

1583 return false;

1584 }

1585

1586

1587 recptr += readbytes;

1588 nbytes -= readbytes;

1589 p += readbytes;

1590 }

1591

1592 return true;

1593}

instr_time pgstat_prepare_io_time(bool track_io_guc)

void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)

static void pgstat_report_wait_start(uint32 wait_event_info)

static void pgstat_report_wait_end(void)

#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes)

References Assert(), buf, IOCONTEXT_NORMAL, IOOBJECT_WAL, IOOP_READ, pg_pread, pgstat_count_io_op_time(), pgstat_prepare_io_time(), pgstat_report_wait_end(), pgstat_report_wait_start(), track_wal_io_timing, WALReadError::wre_errno, WALReadError::wre_off, WALReadError::wre_read, WALReadError::wre_req, WALReadError::wre_seg, XLByteInSeg, XLByteToSeg, and XLogSegmentOffset.

Referenced by logical_read_xlog_page(), read_local_xlog_page_guts(), summarizer_read_local_xlog_page(), WALDumpReadPage(), and XLogSendPhysical().

XLogBeginRead()

Definition at line 232 of file xlogreader.c.

233{

235

237

238

239 state->EndRecPtr = RecPtr;

240 state->NextRecPtr = RecPtr;

243}

#define XLogRecPtrIsInvalid(r)

#define InvalidXLogRecPtr

static void ResetDecoder(XLogReaderState *state)

References Assert(), InvalidXLogRecPtr, ResetDecoder(), and XLogRecPtrIsInvalid.

Referenced by DecodingContextFindStartpoint(), extractPageMap(), findLastCheckpoint(), LogicalReplicationSlotHasPendingWal(), LogicalSlotAdvanceAndCheckSnapState(), pg_logical_slot_get_changes_guts(), readOneRecord(), StartLogicalReplication(), SummarizeWAL(), XLogFindNextRecord(), XLogPrefetcherBeginRead(), and XlogReadTwoPhaseData().

XLogDecodeNextRecord()

Definition at line 529 of file xlogreader.c.

530{

534 bool randAccess;

536 total_len;

538 uint32 pageHeaderSize;

539 bool assembled;

540 bool gotheader;

543 char *errormsg;

544

545

546

547

548

549

550 randAccess = false;

551

552

553 state->errormsg_buf[0] = '\0';

554 decoded = NULL;

555

558

559 RecPtr = state->NextRecPtr;

560

562 {

563

564

565

566

567

568

569

570

571 }

572 else

573 {

574

575

576

577

578

579

580

582 randAccess = true;

583 }

584

585restart:

586 state->nonblocking = nonblocking;

587 state->currRecPtr = RecPtr;

588 assembled = false;

589

590 targetPagePtr = RecPtr - (RecPtr % XLOG_BLCKSZ);

591 targetRecOff = RecPtr % XLOG_BLCKSZ;

592

593

594

595

596

597

603 goto err;

604

605

606

607

608

610 if (targetRecOff == 0)

611 {

612

613

614

615 RecPtr += pageHeaderSize;

616 targetRecOff = pageHeaderSize;

617 }

618 else if (targetRecOff < pageHeaderSize)

619 {

622 pageHeaderSize, targetRecOff);

623 goto err;

624 }

625

627 targetRecOff == pageHeaderSize)

628 {

631 goto err;

632 }

633

634

636

637

638

639

640

641

642

643

644

645

646 record = (XLogRecord *) (state->readBuf + RecPtr % XLOG_BLCKSZ);

648

649

650

651

652

653

654

655

656

658 {

660 randAccess))

661 goto err;

662 gotheader = true;

663 }

664 else

665 {

666

668 {

670 "invalid record length at %X/%X: expected at least %u, got %u",

673 goto err;

674 }

675

676 gotheader = false;

677 }

678

679

680

681

682

683

685 total_len,

686 false );

687 if (decoded == NULL && nonblocking)

688 {

689

690

691

692

693

695 }

696

697 len = XLOG_BLCKSZ - RecPtr % XLOG_BLCKSZ;

698 if (total_len > len)

699 {

700

701 char *contdata;

703 char *buffer;

705

706 assembled = true;

707

708

709

710

711

712 Assert(state->readRecordBufSize >= XLOG_BLCKSZ * 2);

714

715

716 memcpy(state->readRecordBuf,

717 state->readBuf + RecPtr % XLOG_BLCKSZ, len);

718 buffer = state->readRecordBuf + len;

719 gotlen = len;

720

721 do

722 {

723

724 targetPagePtr += XLOG_BLCKSZ;

725

726

729 XLOG_BLCKSZ));

730

734 goto err;

735

737

739

740

741

742

743

744

745

746

747

749 {

750 state->overwrittenRecPtr = RecPtr;

751 RecPtr = targetPagePtr;

752 goto restart;

753 }

754

755

757 {

759 "there is no contrecord flag at %X/%X",

761 goto err;

762 }

763

764

765

766

767

769 total_len != (pageHeader->xlp_rem_len + gotlen))

770 {

772 "invalid contrecord length %u (expected %lld) at %X/%X",

774 ((long long) total_len) - gotlen,

776 goto err;

777 }

778

779

781

782 if (readOff < pageHeaderSize)

784 pageHeaderSize);

785

787

788 contdata = (char *) state->readBuf + pageHeaderSize;

789 len = XLOG_BLCKSZ - pageHeaderSize;

792

795 pageHeaderSize + len);

796

797 memcpy(buffer, contdata, len);

798 buffer += len;

799 gotlen += len;

800

801

802 if (!gotheader)

803 {

806 record, randAccess))

807 goto err;

808 gotheader = true;

809 }

810

811

812

813

814

815

816

817 if (total_len > state->readRecordBufSize)

818 {

819 char save_copy[XLOG_BLCKSZ * 2];

820

821

822

823

824

826 Assert(gotlen <= state->readRecordBufSize);

827 memcpy(save_copy, state->readRecordBuf, gotlen);

829 memcpy(state->readRecordBuf, save_copy, gotlen);

830 buffer = state->readRecordBuf + gotlen;

831 }

832 } while (gotlen < total_len);

834

837 goto err;

838

840 state->DecodeRecPtr = RecPtr;

841 state->NextRecPtr = targetPagePtr + pageHeaderSize

843 }

844 else

845 {

846

848 Min(targetRecOff + total_len, XLOG_BLCKSZ));

852 goto err;

853

854

856 goto err;

857

858 state->NextRecPtr = RecPtr + MAXALIGN(total_len);

859

860 state->DecodeRecPtr = RecPtr;

861 }

862

863

864

865

866 if (record->xl_rmid == RM_XLOG_ID &&

868 {

869

870 state->NextRecPtr += state->segcxt.ws_segsize - 1;

872 }

873

874

875

876

877

878 if (decoded == NULL)

879 {

880 Assert(!nonblocking);

882 total_len,

883 true );

884

885 Assert(decoded != NULL);

886 }

887

889 {

890

892

893

894

895

896

898 {

899

901 if ((char *) decoded == state->decode_buffer)

902 state->decode_buffer_tail = state->decode_buffer + decoded->size;

903 else

904 state->decode_buffer_tail += decoded->size;

905 }

906

907

908 Assert(state->decode_queue_tail != decoded);

909 if (state->decode_queue_tail)

910 state->decode_queue_tail->next = decoded;

911 state->decode_queue_tail = decoded;

912 if (state->decode_queue_head)

913 state->decode_queue_head = decoded;

915 }

916

918 if (assembled)

919 {

920

921

922

923

924

925

926

927

928

929 state->abortedRecPtr = RecPtr;

930 state->missingContrecPtr = targetPagePtr;

931

932

933

934

935

936

937 state->errormsg_deferred = true;

938 }

939

940 if (decoded && decoded->oversized)

942

943

944

945

946

948

949

950

951

952

953

954

956}

#define XLP_FIRST_IS_CONTRECORD

#define XLP_FIRST_IS_OVERWRITE_CONTRECORD

#define XRecOffIsValid(xlrp)

static int ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)

static void static void allocate_recordbuf(XLogReaderState *state, uint32 reclength)

bool DecodeXLogRecord(XLogReaderState *state, DecodedXLogRecord *decoded, XLogRecord *record, XLogRecPtr lsn, char **errormsg)

static bool ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)

static DecodedXLogRecord * XLogReadRecordAlloc(XLogReaderState *state, size_t xl_tot_len, bool allow_oversized)

static bool ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, XLogRecPtr PrevRecPtr, XLogRecord *record, bool randAccess)

References allocate_recordbuf(), Assert(), DecodeXLogRecord(), err(), if(), InvalidXLogRecPtr, len, lengthof, LSN_FORMAT_ARGS, MAXALIGN, Min, state::next, DecodedXLogRecord::next_lsn, DecodedXLogRecord::oversized, pfree(), readOff, ReadPageInternal(), report_invalid_record(), DecodedXLogRecord::size, SizeOfXLogRecord, SizeOfXLogShortPHD, ValidXLogRecord(), ValidXLogRecordHeader(), XLogRecord::xl_info, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLOG_SWITCH, XLogPageHeaderSize, XLogReaderInvalReadState(), XLogReadRecordAlloc(), XLogSegmentOffset, XLP_FIRST_IS_CONTRECORD, XLP_FIRST_IS_OVERWRITE_CONTRECORD, XLogPageHeaderData::xlp_info, XLogPageHeaderData::xlp_rem_len, XLR_INFO_MASK, XLREAD_FAIL, XLREAD_SUCCESS, XLREAD_WOULDBLOCK, and XRecOffIsValid.

Referenced by XLogReadAhead().

XLogFindNextRecord()

Definition at line 1384 of file xlogreader.c.

1385{

1389 char *errormsg;

1390

1392

1393

1394 state->nonblocking = false;

1395

1396

1397

1398

1399

1400 tmpRecPtr = RecPtr;

1401 while (true)

1402 {

1404 int targetRecOff;

1405 uint32 pageHeaderSize;

1407

1408

1409

1410

1411

1412

1413

1414

1415

1416

1417 targetRecOff = tmpRecPtr % XLOG_BLCKSZ;

1418

1419

1420 targetPagePtr = tmpRecPtr - targetRecOff;

1421

1422

1425 goto err;

1426

1428

1430

1431

1434 goto err;

1435

1436

1438 {

1439

1440

1441

1442

1443

1444

1445

1446

1447

1449 tmpRecPtr = targetPagePtr + XLOG_BLCKSZ;

1450 else

1451 {

1452

1453

1454

1455

1456 tmpRecPtr = targetPagePtr + pageHeaderSize

1458 break;

1459 }

1460 }

1461 else

1462 {

1463 tmpRecPtr = targetPagePtr + pageHeaderSize;

1464 break;

1465 }

1466 }

1467

1468

1469

1470

1471

1472

1475 {

1476

1477 if (RecPtr <= state->ReadRecPtr)

1478 {

1479

1480 found = state->ReadRecPtr;

1482 return found;

1483 }

1484 }

1485

1488

1490}

XLogRecord * XLogReadRecord(XLogReaderState *state, char **errormsg)

void XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr)

References Assert(), err(), InvalidXLogRecPtr, MAXALIGN, readLen, ReadPageInternal(), XLogBeginRead(), XLogPageHeaderSize, XLogReaderInvalReadState(), XLogReadRecord(), XLogRecPtrIsInvalid, XLP_FIRST_IS_CONTRECORD, XLogPageHeaderData::xlp_info, and XLogPageHeaderData::xlp_rem_len.

Referenced by InitXLogReaderState(), main(), and SummarizeWAL().

XLogNextRecord()

XLogReadAhead()

XLogReaderAllocate()

Definition at line 107 of file xlogreader.c.

109{

111

116 return NULL;

117

118

119 state->routine = *routine;

120

121

122

123

124

125

126

127

130 if (state->readBuf)

131 {

133 return NULL;

134 }

135

136

138 waldir);

139

140

141 state->private_data = private_data;

142

145 if (state->errormsg_buf)

146 {

149 return NULL;

150 }

151 state->errormsg_buf[0] = '\0';

152

153

154

155

156

159}

#define MCXT_ALLOC_NO_OOM

void * palloc_extended(Size size, int flags)

static void WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt, int segsize, const char *waldir)

References allocate_recordbuf(), MAX_ERRORMSG_LEN, MCXT_ALLOC_NO_OOM, MCXT_ALLOC_ZERO, palloc_extended(), pfree(), wal_segment_size, and WALOpenSegmentInit().

Referenced by extractPageMap(), findLastCheckpoint(), InitWalRecovery(), InitXLogReaderState(), main(), readOneRecord(), StartReplication(), StartupDecodingContext(), SummarizeWAL(), XLogInsertRecord(), and XlogReadTwoPhaseData().

XLogReaderFree()

Definition at line 162 of file xlogreader.c.

163{

164 if (state->seg.ws_file != -1)

166

167 if (state->decode_buffer && state->free_decode_buffer)

169

171 if (state->readRecordBuf)

175}

References pfree().

Referenced by extractPageMap(), findLastCheckpoint(), FreeDecodingContext(), GetWALRecordsInfo(), main(), pg_get_wal_block_info(), pg_get_wal_record_info(), readOneRecord(), ShutdownWalRecovery(), SummarizeWAL(), and XlogReadTwoPhaseData().

XLogReaderInvalReadState()

XLogReaderResetError()

XLogReaderSetDecodeBuffer()

void XLogReaderSetDecodeBuffer ( XLogReaderState * state,
void * buffer,
size_t size
)

XLogReaderValidatePageHeader()

Definition at line 1225 of file xlogreader.c.

1227{

1231

1232 Assert((recptr % XLOG_BLCKSZ) == 0);

1233

1236

1238 {

1240

1242

1244 "invalid magic number %04X in WAL segment %s, LSN %X/%X, offset %u",

1246 fname,

1248 offset);

1249 return false;

1250 }

1251

1253 {

1255

1257

1259 "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u",

1261 fname,

1263 offset);

1264 return false;

1265 }

1266

1268 {

1270

1271 if (state->system_identifier &&

1273 {

1275 "WAL file is from different database system: WAL file database system identifier is %" PRIu64 ", pg_control database system identifier is %" PRIu64,

1277 state->system_identifier);

1278 return false;

1279 }

1281 {

1283 "WAL file is from different database system: incorrect segment size in page header");

1284 return false;

1285 }

1287 {

1289 "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header");

1290 return false;

1291 }

1292 }

1293 else if (offset == 0)

1294 {

1296

1298

1299

1301 "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u",

1303 fname,

1305 offset);

1306 return false;

1307 }

1308

1309

1310

1311

1312

1313

1315 {

1317

1319

1321 "unexpected pageaddr %X/%X in WAL segment %s, LSN %X/%X, offset %u",

1323 fname,

1325 offset);

1326 return false;

1327 }

1328

1329

1330

1331

1332

1333

1334

1335

1336

1337

1338 if (recptr > state->latestPagePtr)

1339 {

1341 {

1343

1345

1347 "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%X, offset %u",

1349 state->latestPageTLI,

1350 fname,

1352 offset);

1353 return false;

1354 }

1355 }

1356 state->latestPagePtr = recptr;

1358

1359 return true;

1360}

XLogLongPageHeaderData * XLogLongPageHeader

static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References Assert(), LSN_FORMAT_ARGS, MAXFNAMELEN, report_invalid_record(), XLByteToSeg, XLOG_PAGE_MAGIC, XLogFileName(), XLogSegmentOffset, XLP_ALL_FLAGS, XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, and XLogLongPageHeaderData::xlp_xlog_blcksz.

Referenced by ReadPageInternal(), and XLogPageRead().

XLogReadRecord()

Definition at line 390 of file xlogreader.c.

391{

393

394

395

396

397

399

400

401

402

403

406

407

409 if (decoded)

410 {

411

412

413

414

415

416

418 return &decoded->header;

419 }

420

421 return NULL;

422}

DecodedXLogRecord * XLogReadAhead(XLogReaderState *state, bool nonblocking)

DecodedXLogRecord * XLogNextRecord(XLogReaderState *state, char **errormsg)

static bool XLogReaderHasQueuedRecordOrError(XLogReaderState *state)

References Assert(), DecodedXLogRecord::header, XLogNextRecord(), XLogReadAhead(), XLogReaderHasQueuedRecordOrError(), and XLogReleasePreviousRecord().

Referenced by DecodingContextFindStartpoint(), extractPageMap(), findLastCheckpoint(), LogicalReplicationSlotHasPendingWal(), LogicalSlotAdvanceAndCheckSnapState(), main(), pg_logical_slot_get_changes_guts(), ReadNextXLogRecord(), readOneRecord(), SummarizeWAL(), XLogFindNextRecord(), XlogReadTwoPhaseData(), and XLogSendLogical().

XLogReadRecordAlloc()

Definition at line 439 of file xlogreader.c.

440{

443

444

446 {

447 if (state->decode_buffer_size == 0)

450 state->decode_buffer_head = state->decode_buffer;

451 state->decode_buffer_tail = state->decode_buffer;

452 state->free_decode_buffer = true;

453 }

454

455

456 if (state->decode_buffer_tail >= state->decode_buffer_head)

457 {

458

459 if (required_space <=

460 state->decode_buffer_size -

461 (state->decode_buffer_tail - state->decode_buffer))

462 {

463

464

465

466

467

468

469

470

471

472

475 return decoded;

476 }

477 else if (required_space <

478 state->decode_buffer_head - state->decode_buffer)

479 {

480

481

482

483

484

485

486

487

488

489

492 return decoded;

493 }

494 }

495 else

496 {

497

498 if (required_space <

499 state->decode_buffer_head - state->decode_buffer_tail)

500 {

501

502

503

504

505

506

507

508

509

510

513 return decoded;

514 }

515 }

516

517

518 if (allow_oversized)

519 {

520 decoded = palloc(required_space);

522 return decoded;

523 }

524

525 return NULL;

526}

#define DEFAULT_DECODE_BUFFER_SIZE

References DecodeXLogRecordRequiredSpace(), DEFAULT_DECODE_BUFFER_SIZE, DecodedXLogRecord::oversized, palloc(), and unlikely.

Referenced by XLogDecodeNextRecord().

XLogRecGetBlockData()

Definition at line 2035 of file xlogreader.c.

2036{

2038

2041 return NULL;

2042

2044

2046 {

2047 if (len)

2048 *len = 0;

2049 return NULL;

2050 }

2051 else

2052 {

2053 if (len)

2055 return bkpb->data;

2056 }

2057}

References DecodedXLogRecord::blocks, DecodedBkpBlock::data, DecodedBkpBlock::data_len, DecodedBkpBlock::has_data, DecodedBkpBlock::in_use, len, DecodedXLogRecord::max_block_id, and XLogReaderState::record.

Referenced by _bt_restore_meta(), brin_xlog_insert_update(), brin_xlog_samepage_update(), btree_desc(), btree_xlog_dedup(), btree_xlog_delete(), btree_xlog_insert(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_vacuum(), DecodeInsert(), DecodeMultiInsert(), DecodeUpdate(), generic_redo(), gin_desc(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), hash_xlog_add_ovfl_page(), hash_xlog_delete(), hash_xlog_insert(), hash_xlog_move_page_contents(), hash_xlog_split_allocate_page(), hash_xlog_squeeze_page(), heap2_desc(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_prune_freeze(), and heap_xlog_update().

XLogRecGetBlockTag()

Definition at line 1981 of file xlogreader.c.

1984{

1986 blknum, NULL))

1987 {

1988#ifndef FRONTEND

1989 elog(ERROR, "could not locate backup block with ID %d in WAL record",

1990 block_id);

1991#else

1992 pg_fatal("could not locate backup block with ID %d in WAL record",

1993 block_id);

1994#endif

1995 }

1996}

bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum, Buffer *prefetch_buffer)

References elog, ERROR, pg_fatal, and XLogRecGetBlockTagExtended().

Referenced by brin_xlog_revmap_extend(), btree_xlog_delete(), btree_xlog_split(), DecodeDelete(), DecodeInsert(), DecodeMultiInsert(), DecodeSpecConfirm(), DecodeUpdate(), gistRedoDeleteRecord(), gistRedoPageSplitRecord(), hash_xlog_add_ovfl_page(), hash_xlog_init_bitmap_page(), hash_xlog_init_meta_page(), hash_xlog_vacuum_one_page(), heap_xlog_delete(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_prune_freeze(), heap_xlog_update(), heap_xlog_visible(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), and spgRedoVacuumRedirect().

XLogRecGetBlockTagExtended()

Definition at line 2007 of file xlogreader.c.

2011{

2013

2015 return false;

2016

2018 if (rlocator)

2020 if (forknum)

2021 *forknum = bkpb->forknum;

2022 if (blknum)

2023 *blknum = bkpb->blkno;

2024 if (prefetch_buffer)

2026 return true;

2027}

#define XLogRecHasBlockRef(decoder, block_id)

References DecodedBkpBlock::blkno, DecodedXLogRecord::blocks, DecodedBkpBlock::forknum, DecodedBkpBlock::prefetch_buffer, XLogReaderState::record, DecodedBkpBlock::rlocator, and XLogRecHasBlockRef.

Referenced by btree_xlog_split(), extractPageInfo(), GetWALBlockInfo(), heap_xlog_update(), SummarizeWAL(), verifyBackupPageConsistency(), xlog_block_info(), XLogReadBufferForRedoExtended(), XLogRecGetBlockRefInfo(), XLogRecGetBlockTag(), XLogRecordMatchesRelationBlock(), and XLogRecordSaveFPWs().

XLogRecGetFullXid()

XLogReleasePreviousRecord()