aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/nbtree/nbtpage.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2023-04-01 20:12:26 -0700
committerAndres Freund <andres@anarazel.de>2023-04-01 20:18:29 -0700
commit61b313e47eb987682441c675724c22bf4363c9c4 (patch)
treed3cc190f131f23fa00e4d25edcff6d06b1499498 /src/backend/access/nbtree/nbtpage.c
parenta88a18b1250b9e6b40536e4dec04d32d655b8140 (diff)
downloadpostgresql-61b313e47eb987682441c675724c22bf4363c9c4.tar.gz
postgresql-61b313e47eb987682441c675724c22bf4363c9c4.zip
Pass down table relation into more index relation functions
This is done in preparation for logical decoding on standby, which needs to include whether visibility affecting WAL records are about a (user) catalog table. Which is only known for the table, not the indexes. It's also nice to be able to pass the heap relation to GlobalVisTestFor() in vacuumRedirectAndPlaceholder(). Author: "Drouvot, Bertrand" <bertranddrouvot.pg@gmail.com> Discussion: https://postgr.es/m/21b700c3-eecf-2e05-a699-f8c78dd31ec7@gmail.com
Diffstat (limited to 'src/backend/access/nbtree/nbtpage.c')
-rw-r--r--src/backend/access/nbtree/nbtpage.c109
1 files changed, 57 insertions, 52 deletions
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index 3feee28d197..ee996b56602 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -38,25 +38,24 @@
#include "utils/snapmgr.h"
static BTMetaPageData *_bt_getmeta(Relation rel, Buffer metabuf);
-static void _bt_log_reuse_page(Relation rel, BlockNumber blkno,
+static void _bt_log_reuse_page(Relation rel, Relation heaprel, BlockNumber blkno,
FullTransactionId safexid);
-static void _bt_delitems_delete(Relation rel, Buffer buf,
+static void _bt_delitems_delete(Relation rel, Relation heaprel, Buffer buf,
TransactionId snapshotConflictHorizon,
OffsetNumber *deletable, int ndeletable,
BTVacuumPosting *updatable, int nupdatable);
static char *_bt_delitems_update(BTVacuumPosting *updatable, int nupdatable,
OffsetNumber *updatedoffsets,
Size *updatedbuflen, bool needswal);
-static bool _bt_mark_page_halfdead(Relation rel, Buffer leafbuf,
- BTStack stack);
+static bool _bt_mark_page_halfdead(Relation rel, Relation heaprel,
+ Buffer leafbuf, BTStack stack);
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,
+static bool _bt_lock_subtree_parent(Relation rel, Relation heaprel,
+ BlockNumber child, BTStack stack,
+ Buffer *subtreeparent, OffsetNumber *poffset,
BlockNumber *topparent,
BlockNumber *topparentrightsib);
static void _bt_pendingfsm_add(BTVacState *vstate, BlockNumber target,
@@ -178,7 +177,7 @@ _bt_getmeta(Relation rel, Buffer metabuf)
* index tuples needed to be deleted.
*/
bool
-_bt_vacuum_needs_cleanup(Relation rel)
+_bt_vacuum_needs_cleanup(Relation rel, Relation heaprel)
{
Buffer metabuf;
Page metapg;
@@ -191,7 +190,7 @@ _bt_vacuum_needs_cleanup(Relation rel)
*
* Note that we deliberately avoid using cached version of metapage here.
*/
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metapg = BufferGetPage(metabuf);
metad = BTPageGetMeta(metapg);
btm_version = metad->btm_version;
@@ -231,7 +230,7 @@ _bt_vacuum_needs_cleanup(Relation rel)
* finalized.
*/
void
-_bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
+_bt_set_cleanup_info(Relation rel, Relation heaprel, BlockNumber num_delpages)
{
Buffer metabuf;
Page metapg;
@@ -255,7 +254,7 @@ _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
* no longer used as of PostgreSQL 14. We set it to -1.0 on rewrite, just
* to be consistent.
*/
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metapg = BufferGetPage(metabuf);
metad = BTPageGetMeta(metapg);
@@ -340,7 +339,7 @@ _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
* The metadata page is not locked or pinned on exit.
*/
Buffer
-_bt_getroot(Relation rel, int access)
+_bt_getroot(Relation rel, Relation heaprel, int access)
{
Buffer metabuf;
Buffer rootbuf;
@@ -370,7 +369,7 @@ _bt_getroot(Relation rel, int access)
Assert(rootblkno != P_NONE);
rootlevel = metad->btm_fastlevel;
- rootbuf = _bt_getbuf(rel, rootblkno, BT_READ);
+ rootbuf = _bt_getbuf(rel, heaprel, rootblkno, BT_READ);
rootpage = BufferGetPage(rootbuf);
rootopaque = BTPageGetOpaque(rootpage);
@@ -396,7 +395,7 @@ _bt_getroot(Relation rel, int access)
rel->rd_amcache = NULL;
}
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metad = _bt_getmeta(rel, metabuf);
/* if no root page initialized yet, do it */
@@ -429,7 +428,7 @@ _bt_getroot(Relation rel, int access)
* to optimize this case.)
*/
_bt_relbuf(rel, metabuf);
- return _bt_getroot(rel, access);
+ return _bt_getroot(rel, heaprel, access);
}
/*
@@ -437,7 +436,7 @@ _bt_getroot(Relation rel, int access)
* the new root page. Since this is the first page in the tree, it's
* a leaf as well as the root.
*/
- rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
+ rootbuf = _bt_getbuf(rel, heaprel, P_NEW, BT_WRITE);
rootblkno = BufferGetBlockNumber(rootbuf);
rootpage = BufferGetPage(rootbuf);
rootopaque = BTPageGetOpaque(rootpage);
@@ -574,7 +573,7 @@ _bt_getroot(Relation rel, int access)
* moving to the root --- that'd deadlock against any concurrent root split.)
*/
Buffer
-_bt_gettrueroot(Relation rel)
+_bt_gettrueroot(Relation rel, Relation heaprel)
{
Buffer metabuf;
Page metapg;
@@ -596,7 +595,7 @@ _bt_gettrueroot(Relation rel)
pfree(rel->rd_amcache);
rel->rd_amcache = NULL;
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metapg = BufferGetPage(metabuf);
metaopaque = BTPageGetOpaque(metapg);
metad = BTPageGetMeta(metapg);
@@ -669,7 +668,7 @@ _bt_gettrueroot(Relation rel)
* about updating previously cached data.
*/
int
-_bt_getrootheight(Relation rel)
+_bt_getrootheight(Relation rel, Relation heaprel)
{
BTMetaPageData *metad;
@@ -677,7 +676,7 @@ _bt_getrootheight(Relation rel)
{
Buffer metabuf;
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metad = _bt_getmeta(rel, metabuf);
/*
@@ -733,7 +732,7 @@ _bt_getrootheight(Relation rel)
* pg_upgrade'd from Postgres 12.
*/
void
-_bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
+_bt_metaversion(Relation rel, Relation heaprel, bool *heapkeyspace, bool *allequalimage)
{
BTMetaPageData *metad;
@@ -741,7 +740,7 @@ _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
{
Buffer metabuf;
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metabuf = _bt_getbuf(rel, heaprel, BTREE_METAPAGE, BT_READ);
metad = _bt_getmeta(rel, metabuf);
/*
@@ -825,7 +824,8 @@ _bt_checkpage(Relation rel, Buffer buf)
* Log the reuse of a page from the FSM.
*/
static void
-_bt_log_reuse_page(Relation rel, BlockNumber blkno, FullTransactionId safexid)
+_bt_log_reuse_page(Relation rel, Relation heaprel, BlockNumber blkno,
+ FullTransactionId safexid)
{
xl_btree_reuse_page xlrec_reuse;
@@ -868,7 +868,7 @@ _bt_log_reuse_page(Relation rel, BlockNumber blkno, FullTransactionId safexid)
* as _bt_lockbuf().
*/
Buffer
-_bt_getbuf(Relation rel, BlockNumber blkno, int access)
+_bt_getbuf(Relation rel, Relation heaprel, BlockNumber blkno, int access)
{
Buffer buf;
@@ -943,7 +943,7 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
* than safexid value
*/
if (XLogStandbyInfoActive() && RelationNeedsWAL(rel))
- _bt_log_reuse_page(rel, blkno,
+ _bt_log_reuse_page(rel, heaprel, blkno,
BTPageGetDeleteXid(page));
/* Okay to use page. Re-initialize and return it. */
@@ -1293,7 +1293,7 @@ _bt_delitems_vacuum(Relation rel, Buffer buf,
* clear page's VACUUM cycle ID.
*/
static void
-_bt_delitems_delete(Relation rel, Buffer buf,
+_bt_delitems_delete(Relation rel, Relation heaprel, Buffer buf,
TransactionId snapshotConflictHorizon,
OffsetNumber *deletable, int ndeletable,
BTVacuumPosting *updatable, int nupdatable)
@@ -1684,8 +1684,8 @@ _bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel,
}
/* Physically delete tuples (or TIDs) using deletable (or updatable) */
- _bt_delitems_delete(rel, buf, snapshotConflictHorizon,
- deletable, ndeletable, updatable, nupdatable);
+ _bt_delitems_delete(rel, heapRel, buf, snapshotConflictHorizon, deletable,
+ ndeletable, updatable, nupdatable);
/* be tidy */
for (int i = 0; i < nupdatable; i++)
@@ -1706,7 +1706,8 @@ _bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel,
* same level must always be locked left to right to avoid deadlocks.
*/
static bool
-_bt_leftsib_splitflag(Relation rel, BlockNumber leftsib, BlockNumber target)
+_bt_leftsib_splitflag(Relation rel, Relation heaprel, BlockNumber leftsib,
+ BlockNumber target)
{
Buffer buf;
Page page;
@@ -1717,7 +1718,7 @@ _bt_leftsib_splitflag(Relation rel, BlockNumber leftsib, BlockNumber target)
if (leftsib == P_NONE)
return false;
- buf = _bt_getbuf(rel, leftsib, BT_READ);
+ buf = _bt_getbuf(rel, heaprel, leftsib, BT_READ);
page = BufferGetPage(buf);
opaque = BTPageGetOpaque(page);
@@ -1763,7 +1764,7 @@ _bt_leftsib_splitflag(Relation rel, BlockNumber leftsib, BlockNumber target)
* to-be-deleted subtree.)
*/
static bool
-_bt_rightsib_halfdeadflag(Relation rel, BlockNumber leafrightsib)
+_bt_rightsib_halfdeadflag(Relation rel, Relation heaprel, BlockNumber leafrightsib)
{
Buffer buf;
Page page;
@@ -1772,7 +1773,7 @@ _bt_rightsib_halfdeadflag(Relation rel, BlockNumber leafrightsib)
Assert(leafrightsib != P_NONE);
- buf = _bt_getbuf(rel, leafrightsib, BT_READ);
+ buf = _bt_getbuf(rel, heaprel, leafrightsib, BT_READ);
page = BufferGetPage(buf);
opaque = BTPageGetOpaque(page);
@@ -1961,17 +1962,18 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
* marked with INCOMPLETE_SPLIT flag before proceeding
*/
Assert(leafblkno == scanblkno);
- if (_bt_leftsib_splitflag(rel, leftsib, leafblkno))
+ if (_bt_leftsib_splitflag(rel, vstate->info->heaprel, leftsib, leafblkno))
{
ReleaseBuffer(leafbuf);
return;
}
/* we need an insertion scan key for the search, so build one */
- itup_key = _bt_mkscankey(rel, targetkey);
+ itup_key = _bt_mkscankey(rel, vstate->info->heaprel, targetkey);
/* find the leftmost leaf page with matching pivot/high key */
itup_key->pivotsearch = true;
- stack = _bt_search(rel, itup_key, &sleafbuf, BT_READ, NULL);
+ stack = _bt_search(rel, vstate->info->heaprel, itup_key,
+ &sleafbuf, BT_READ, NULL);
/* won't need a second lock or pin on leafbuf */
_bt_relbuf(rel, sleafbuf);
@@ -2002,7 +2004,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
* leafbuf page half-dead.
*/
Assert(P_ISLEAF(opaque) && !P_IGNORE(opaque));
- if (!_bt_mark_page_halfdead(rel, leafbuf, stack))
+ if (!_bt_mark_page_halfdead(rel, vstate->info->heaprel, leafbuf, stack))
{
_bt_relbuf(rel, leafbuf);
return;
@@ -2065,7 +2067,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
if (!rightsib_empty)
break;
- leafbuf = _bt_getbuf(rel, rightsib, BT_WRITE);
+ leafbuf = _bt_getbuf(rel, vstate->info->heaprel, rightsib, BT_WRITE);
}
}
@@ -2084,7 +2086,8 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
* successfully.
*/
static bool
-_bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
+_bt_mark_page_halfdead(Relation rel, Relation heaprel, Buffer leafbuf,
+ BTStack stack)
{
BlockNumber leafblkno;
BlockNumber leafrightsib;
@@ -2119,7 +2122,7 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
* delete the downlink. It would fail the "right sibling of target page
* is also the next child in parent page" cross-check below.
*/
- if (_bt_rightsib_halfdeadflag(rel, leafrightsib))
+ if (_bt_rightsib_halfdeadflag(rel, heaprel, leafrightsib))
{
elog(DEBUG1, "could not delete page %u because its right sibling %u is half-dead",
leafblkno, leafrightsib);
@@ -2143,7 +2146,7 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
*/
topparent = leafblkno;
topparentrightsib = leafrightsib;
- if (!_bt_lock_subtree_parent(rel, leafblkno, stack,
+ if (!_bt_lock_subtree_parent(rel, heaprel, leafblkno, stack,
&subtreeparent, &poffset,
&topparent, &topparentrightsib))
return false;
@@ -2363,7 +2366,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
Assert(target != leafblkno);
/* Fetch the block number of the target's left sibling */
- buf = _bt_getbuf(rel, target, BT_READ);
+ buf = _bt_getbuf(rel, vstate->info->heaprel, target, BT_READ);
page = BufferGetPage(buf);
opaque = BTPageGetOpaque(page);
leftsib = opaque->btpo_prev;
@@ -2390,7 +2393,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
_bt_lockbuf(rel, leafbuf, BT_WRITE);
if (leftsib != P_NONE)
{
- lbuf = _bt_getbuf(rel, leftsib, BT_WRITE);
+ lbuf = _bt_getbuf(rel, vstate->info->heaprel, leftsib, BT_WRITE);
page = BufferGetPage(lbuf);
opaque = BTPageGetOpaque(page);
while (P_ISDELETED(opaque) || opaque->btpo_next != target)
@@ -2440,7 +2443,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
CHECK_FOR_INTERRUPTS();
/* step right one page */
- lbuf = _bt_getbuf(rel, leftsib, BT_WRITE);
+ lbuf = _bt_getbuf(rel, vstate->info->heaprel, leftsib, BT_WRITE);
page = BufferGetPage(lbuf);
opaque = BTPageGetOpaque(page);
}
@@ -2504,7 +2507,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
* And next write-lock the (current) right sibling.
*/
rightsib = opaque->btpo_next;
- rbuf = _bt_getbuf(rel, rightsib, BT_WRITE);
+ rbuf = _bt_getbuf(rel, vstate->info->heaprel, rightsib, BT_WRITE);
page = BufferGetPage(rbuf);
opaque = BTPageGetOpaque(page);
if (opaque->btpo_prev != target)
@@ -2533,7 +2536,8 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
if (P_RIGHTMOST(opaque))
{
/* rightsib will be the only one left on the level */
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
+ metabuf = _bt_getbuf(rel, vstate->info->heaprel, BTREE_METAPAGE,
+ BT_WRITE);
metapg = BufferGetPage(metabuf);
metad = BTPageGetMeta(metapg);
@@ -2773,9 +2777,10 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
* parent block in the leafbuf page using BTreeTupleSetTopParent()).
*/
static bool
-_bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack,
- Buffer *subtreeparent, OffsetNumber *poffset,
- BlockNumber *topparent, BlockNumber *topparentrightsib)
+_bt_lock_subtree_parent(Relation rel, Relation heaprel, BlockNumber child,
+ BTStack stack, Buffer *subtreeparent,
+ OffsetNumber *poffset, BlockNumber *topparent,
+ BlockNumber *topparentrightsib)
{
BlockNumber parent,
leftsibparent;
@@ -2789,7 +2794,7 @@ _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack,
* Locate the pivot tuple whose downlink points to "child". Write lock
* the parent page itself.
*/
- pbuf = _bt_getstackbuf(rel, stack, child);
+ pbuf = _bt_getstackbuf(rel, heaprel, stack, child);
if (pbuf == InvalidBuffer)
{
/*
@@ -2889,11 +2894,11 @@ _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack,
*
* Note: We deliberately avoid completing incomplete splits here.
*/
- if (_bt_leftsib_splitflag(rel, leftsibparent, parent))
+ if (_bt_leftsib_splitflag(rel, heaprel, leftsibparent, parent))
return false;
/* Recurse to examine child page's grandparent page */
- return _bt_lock_subtree_parent(rel, parent, stack->bts_parent,
+ return _bt_lock_subtree_parent(rel, heaprel, parent, stack->bts_parent,
subtreeparent, poffset,
topparent, topparentrightsib);
}