49 Size *updatedbuflen,
bool needswal);
158 (
errcode(ERRCODE_INDEX_CORRUPTED),
159 errmsg(
"index \"%s\" is not a btree",
165 (
errcode(ERRCODE_INDEX_CORRUPTED),
166 errmsg(
"version mismatch in index \"%s\": file version %d, "
167 "current version %d, minimal supported version %d",
220 if (prev_num_delpages > 0 &&
544 elog(
ERROR,
"no live root page found in index \"%s\"",
550 elog(
ERROR,
"root page %u of index \"%s\" has level %u, expected %u",
607 (
errcode(ERRCODE_INDEX_CORRUPTED),
608 errmsg(
"index \"%s\" is not a btree",
614 (
errcode(ERRCODE_INDEX_CORRUPTED),
615 errmsg(
"version mismatch in index \"%s\": file version %d, "
616 "current version %d, minimal supported version %d",
647 elog(
ERROR,
"no live root page found in index \"%s\"",
653 elog(
ERROR,
"root page %u of index \"%s\" has level %u, expected %u",
806 (
errcode(ERRCODE_INDEX_CORRUPTED),
807 errmsg(
"index \"%s\" contains unexpected zero page at block %u",
810 errhint(
"Please REINDEX it.")));
817 (
errcode(ERRCODE_INDEX_CORRUPTED),
818 errmsg(
"index \"%s\" contains corrupted page at block %u",
821 errhint(
"Please REINDEX it.")));
840 xlrec_reuse.
block = blkno;
953 elog(
DEBUG2,
"FSM returned nonrecyclable page");
958 elog(
DEBUG2,
"FSM returned nonlockable page");
1173 char *updatedbuf = NULL;
1174 Size updatedbuflen = 0;
1178 Assert(ndeletable > 0 || nupdatable > 0);
1183 updatedoffsets, &updatedbuflen,
1201 for (
int i = 0;
i < nupdatable;
i++)
1207 itup = updatable[
i]->
itup;
1211 elog(
PANIC,
"failed to update partially dead item in block %u of index \"%s\"",
1244 xlrec_vacuum.
ndeleted = ndeletable;
1245 xlrec_vacuum.
nupdated = nupdatable;
1270 if (updatedbuf != NULL)
1273 for (
int i = 0;
i < nupdatable;
i++)
1274 pfree(updatable[
i]->itup);
1304 char *updatedbuf = NULL;
1305 Size updatedbuflen = 0;
1309 Assert(ndeletable > 0 || nupdatable > 0);
1314 updatedoffsets, &updatedbuflen,
1321 for (
int i = 0;
i < nupdatable;
i++)
1327 itup = updatable[
i]->
itup;
1331 elog(
PANIC,
"failed to update partially dead item in block %u of index \"%s\"",
1362 xlrec_delete.
ndeleted = ndeletable;
1363 xlrec_delete.
nupdated = nupdatable;
1388 if (updatedbuf != NULL)
1391 for (
int i = 0;
i < nupdatable;
i++)
1392 pfree(updatable[
i]->itup);
1420 char *updatedbuf = NULL;
1426 for (
int i = 0;
i < nupdatable;
i++)
1448 updatedbuf =
palloc(buflen);
1449 *updatedbuflen = buflen;
1450 for (
int i = 0;
i < nupdatable;
i++)
1462 memcpy(updatedbuf + offset, vacposting->
deletetids, itemsz);
1480 if (indexdelete1->
id > indexdelete2->
id)
1482 if (indexdelete1->
id < indexdelete2->
id)
1579 if (idxoffnum == postingidxoffnum)
1598 deletable[ndeletable++] = idxoffnum;
1610 postingidxoffnum = idxoffnum;
1614 for (
int p = 0; p < nitem; p++)
1625 for (; nestedi < delstate->
ndeltids; nestedi++)
1653 if (vacposting == NULL)
1657 vacposting->
itup = itup;
1666 if (vacposting == NULL)
1673 deletable[ndeletable++] = idxoffnum;
1682 updatable[nupdatable++] = vacposting;
1688 deletable, ndeletable, updatable, nupdatable);
1691 for (
int i = 0;
i < nupdatable;
i++)
1819 bool rightsib_empty;
1874 (
errcode(ERRCODE_INDEX_CORRUPTED),
1875 errmsg(
"index \"%s\" contains a half-dead internal page",
1877 errhint(
"This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it.")));
1881 (
errcode(ERRCODE_INDEX_CORRUPTED),
1882 errmsg_internal(
"found deleted block %u while following right link from block %u in index \"%s\"",
1963 Assert(leafblkno == scanblkno);
2017 rightsib_empty =
false;
2023 &rightsib_empty, vstate))
2065 if (!rightsib_empty)
2124 elog(
DEBUG1,
"could not delete page %u because its right sibling %u is half-dead",
2125 leafblkno, leafrightsib);
2144 topparent = leafblkno;
2145 topparentrightsib = leafrightsib;
2147 &subtreeparent, &poffset,
2148 &topparent, &topparentrightsib))
2160 #ifdef USE_ASSERT_CHECKING
2176 (
errcode(ERRCODE_INDEX_CORRUPTED),
2177 errmsg_internal(
"right sibling %u of block %u is not next child %u of block %u in index \"%s\"",
2178 topparentrightsib, topparent,
2226 if (topparent != leafblkno)
2233 elog(
ERROR,
"could not overwrite high key in half-dead page");
2247 if (topparent != leafblkno)
2323 bool rightsib_is_rightmost;
2357 leftsib = leafleftsib;
2363 Assert(target != leafblkno);
2389 if (target != leafblkno)
2398 bool leftsibvalid =
true;
2411 leftsibvalid =
false;
2418 if (target != leafblkno)
2431 (
errcode(ERRCODE_INDEX_CORRUPTED),
2432 errmsg_internal(
"valid left sibling for deletion target could not be located: "
2433 "left sibling %u of target %u with leafblkno %u and scanblkno %u in index \"%s\"",
2434 leftsib, target, leafblkno, scanblkno,
2462 elog(
ERROR,
"target page changed status unexpectedly in block %u of index \"%s\"",
2467 (
errcode(ERRCODE_INDEX_CORRUPTED),
2468 errmsg_internal(
"target page left link unexpectedly changed from %u to %u in block %u of index \"%s\"",
2472 if (target == leafblkno)
2476 elog(
ERROR,
"target leaf page changed status unexpectedly in block %u of index \"%s\"",
2488 elog(
ERROR,
"target internal page on level %u changed status unexpectedly in block %u of index \"%s\"",
2496 if (leaftopparent == leafblkno)
2512 (
errcode(ERRCODE_INDEX_CORRUPTED),
2514 "block %u links to %u instead of expected %u in index \"%s\"",
2529 if (leftsib ==
P_NONE && rightsib_is_rightmost)
2589 if (target != leafblkno)
2630 if (target != leafblkno)
2647 if (target != leafblkno)
2653 xlrec.
level = targetlevel;
2697 if (target != leafblkno)
2716 if (target != leafblkno)
2729 if (target <= scanblkno)
2808 (
errcode(ERRCODE_INDEX_CORRUPTED),
2809 errmsg_internal(
"failed to re-find parent key in index \"%s\" for deletion target page %u",
2836 if (parentoffset < maxoff)
2842 *subtreeparent = pbuf;
2843 *poffset = parentoffset;
2854 Assert(parentoffset == maxoff);
2872 *topparent = parent;
2897 subtreeparent, poffset,
2898 topparent, topparentrightsib);
2934 maxbufsize =
Min(maxbufsize, INT_MAX);
2937 maxbufsize =
Max(maxbufsize, vstate->
bufsize);
2971 #ifdef DEBUG_BTREE_PENDING_FSM
3028 #ifdef USE_ASSERT_CHECKING
3057 int newbufsize = vstate->
bufsize * 2;
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum)
bool ConditionalLockBuffer(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBufferForCleanup(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BUFFER_LOCK_UNLOCK
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Size BufferGetPageSize(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
void PageInit(Page page, Size pageSize, Size specialSize)
PageHeaderData * PageHeader
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static bool PageIsNew(Page page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
static uint16 PageGetSpecialSize(Page page)
#define MemSet(start, val, len)
#define PG_USED_FOR_ASSERTS_ONLY
elog(ERROR, "%s: %s", p2, msg)
int errmsg_internal(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
BlockNumber GetFreeIndexPage(Relation rel)
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
IndexTuple CopyIndexTuple(IndexTuple source)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
struct IndexTupleData IndexTupleData
#define MaxIndexTuplesPerPage
Assert(fmt[strlen(fmt) - 1] !='\n')
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
void pfree(void *pointer)
void * repalloc(void *pointer, Size size)
void * MemoryContextAlloc(MemoryContext context, Size size)
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_CHECK_MEM_IS_DEFINED(addr, size)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
void _bt_update_posting(BTVacuumPosting vacposting)
Buffer _bt_getstackbuf(Relation rel, BTStack stack, BlockNumber child)
Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, BlockNumber blkno, int access)
void _bt_upgrademetapage(Page page)
void _bt_relbuf(Relation rel, Buffer buf)
Buffer _bt_gettrueroot(Relation rel)
int _bt_getrootheight(Relation rel)
void _bt_pageinit(Page page, Size size)
static bool _bt_rightsib_halfdeadflag(Relation rel, BlockNumber leafrightsib)
void _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
void _bt_delitems_vacuum(Relation rel, Buffer buf, OffsetNumber *deletable, int ndeletable, BTVacuumPosting *updatable, int nupdatable)
Buffer _bt_getroot(Relation rel, int access)
static bool _bt_leftsib_splitflag(Relation rel, BlockNumber leftsib, BlockNumber target)
void _bt_checkpage(Relation rel, Buffer buf)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
static BTMetaPageData * _bt_getmeta(Relation rel, Buffer metabuf)
void _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
bool _bt_conditionallockbuf(Relation rel, Buffer buf)
Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access)
static void _bt_delitems_delete(Relation rel, Buffer buf, TransactionId snapshotConflictHorizon, OffsetNumber *deletable, int ndeletable, BTVacuumPosting *updatable, int nupdatable)
void _bt_unlockbuf(Relation rel, Buffer buf)
void _bt_upgradelockbufcleanup(Relation rel, Buffer buf)
void _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level, bool allequalimage)
void _bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel, TM_IndexDeleteOp *delstate)
bool _bt_vacuum_needs_cleanup(Relation rel)
static bool _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
static char * _bt_delitems_update(BTVacuumPosting *updatable, int nupdatable, OffsetNumber *updatedoffsets, Size *updatedbuflen, bool needswal)
static int _bt_delitems_cmp(const void *a, const void *b)
void _bt_pendingfsm_finalize(Relation rel, BTVacState *vstate)
void _bt_lockbuf(Relation rel, Buffer buf, int access)
static void _bt_log_reuse_page(Relation rel, BlockNumber blkno, FullTransactionId safexid)
void _bt_pendingfsm_init(Relation rel, BTVacState *vstate, bool cleanuponly)
static void _bt_pendingfsm_add(BTVacState *vstate, BlockNumber target, FullTransactionId safexid)
static bool _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, bool *rightsib_empty, BTVacState *vstate)
static bool _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack, Buffer *subtreeparent, OffsetNumber *poffset, BlockNumber *topparent, BlockNumber *topparentrightsib)
#define P_ISHALFDEAD(opaque)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static FullTransactionId BTPageGetDeleteXid(Page page)
#define BTREE_MIN_VERSION
static bool BTPageIsRecyclable(Page page)
static void BTreeTupleSetTopParent(IndexTuple leafhikey, BlockNumber blkno)
#define P_LEFTMOST(opaque)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
static BlockNumber BTreeTupleGetTopParent(IndexTuple leafhikey)
static void BTreeTupleSetDownLink(IndexTuple pivot, BlockNumber blkno)
#define P_FIRSTDATAKEY(opaque)
#define P_RIGHTMOST(opaque)
#define P_INCOMPLETE_SPLIT(opaque)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static BlockNumber BTreeTupleGetDownLink(IndexTuple pivot)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
static void BTPageSetDeleted(Page page, FullTransactionId safexid)
#define BTREE_NOVAC_VERSION
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
BTStack _bt_search(Relation rel, BTScanInsert key, Buffer *bufP, int access, Snapshot snapshot)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
#define SizeOfBtreeVacuum
#define XLOG_BTREE_META_CLEANUP
#define SizeOfBtreeUpdate
#define XLOG_BTREE_VACUUM
#define SizeOfBtreeDelete
#define SizeOfBtreeMarkPageHalfDead
#define XLOG_BTREE_UNLINK_PAGE
#define XLOG_BTREE_UNLINK_PAGE_META
#define SizeOfBtreeNewroot
#define XLOG_BTREE_MARK_PAGE_HALFDEAD
#define XLOG_BTREE_REUSE_PAGE
#define SizeOfBtreeUnlinkPage
#define SizeOfBtreeReusePage
#define XLOG_BTREE_NEWROOT
#define XLOG_BTREE_DELETE
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define qsort(a, b, c, d)
void PredicateLockPageCombine(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
TransactionId GetOldestNonRemovableTransactionId(Relation rel)
bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)
#define RELATION_IS_LOCAL(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define RelationUsesLocalBuffers(relation)
void pg_usleep(long microsec)
uint32 btm_last_cleanup_num_delpages
float8 btm_last_cleanup_num_heap_tuples
FullTransactionId safexid
struct BTStackData * bts_parent
IndexBulkDeleteResult * stats
BTPendingFSM * pendingpages
uint16 deletetids[FLEXIBLE_ARRAY_MEMBER]
OffsetNumber updatedoffset
BlockNumber pages_deleted
BlockNumber pages_newly_deleted
MemoryContext rd_indexcxt
RelFileLocator rd_locator
TransactionId snapshotConflictHorizon
FullTransactionId snapshotConflictHorizon
FullTransactionId safexid
BlockNumber leaftopparent
static TransactionId table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
#define InvalidTransactionId
#define FullTransactionIdFollowsOrEquals(a, b)
FullTransactionId ReadNextFullTransactionId(void)
#define XLogStandbyInfoActive()
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)