Skip to content

Commit

Permalink
brin: Remove upper pages for AO/CO tables
Browse files Browse the repository at this point in the history
This commit removes the upper page architecture for AO/CO tables. This
is in preparation of a rewrite of BRIN for AO/CO tables.

The objective of this commit is to align the existing BRIN code as much
as possible with upstream, and to ensure that tests with BRIN indexes on
heap tables pass. Existing AO/CO tests will fail.

Key points:

(1) Reverted revmap_physical_extend to not returning a BlockNumber. It
was a dead return anyway.

(2) Reverted skipExtend parameter for brin_doupdate(). Its not clear why
this was necessary. It shouldn't be necessary for heap tables.

(3) Kept isAo parameter for metapage and xlog.
  • Loading branch information
soumyadeep2007 authored and reshke committed Jan 10, 2025
1 parent 1a2e8a9 commit 3abbf94
Show file tree
Hide file tree
Showing 10 changed files with 15 additions and 380 deletions.
64 changes: 0 additions & 64 deletions contrib/pageinspect/brinfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ PG_FUNCTION_INFO_V1(brin_page_type);
PG_FUNCTION_INFO_V1(brin_page_items);
PG_FUNCTION_INFO_V1(brin_metapage_info);
PG_FUNCTION_INFO_V1(brin_revmap_data);
PG_FUNCTION_INFO_V1(brin_upper_data);

#define IS_BRIN(r) ((r)->rd_rel->relam == BRIN_AM_OID)

Expand Down Expand Up @@ -82,9 +81,6 @@ brin_page_type(PG_FUNCTION_ARGS)
case BRIN_PAGETYPE_REGULAR:
type = "regular";
break;
case BRIN_PAGETYPE_UPPER:
type = "upper";
break;
default:
type = psprintf("unknown (%02x)", BrinPageType(page));
break;
Expand Down Expand Up @@ -453,63 +449,3 @@ brin_revmap_data(PG_FUNCTION_ARGS)

SRF_RETURN_DONE(fctx);
}


/*
* Return the BlockNumber array stored in a BRIN upper page
*/
Datum
brin_upper_data(PG_FUNCTION_ARGS)
{
struct
{
BlockNumber *blks;
int idx;
} *state;
FuncCallContext *fctx;
ItemPointerData *tid;

if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));

if (SRF_IS_FIRSTCALL())
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
MemoryContext mctx;
Page page;

/* minimally verify the page we got */
page = verify_brin_page(raw_page, BRIN_PAGETYPE_UPPER, "upper");

/* create a function context for cross-call persistence */
fctx = SRF_FIRSTCALL_INIT();

/* switch to memory context appropriate for multiple function calls */
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);

state = palloc(sizeof(*state));
state->blks = ((RevmapUpperBlockContents *) PageGetContents(page))->rm_blocks;
state->idx = 0;

fctx->user_fctx = state;

MemoryContextSwitchTo(mctx);
}

fctx = SRF_PERCALL_SETUP();
state = fctx->user_fctx;


if (state->idx < REVMAP_UPPER_PAGE_MAXITEMS)
{
tid = (ItemPointerData*) palloc(sizeof(ItemPointerData));
ItemPointerSetBlockNumber(tid, (BlockNumber) state->blks[state->idx++]);
ItemPointerSetOffsetNumber(tid, (OffsetNumber) 0);
SRF_RETURN_NEXT(fctx, PointerGetDatum(tid));
}

SRF_RETURN_DONE(fctx);
}

9 changes: 0 additions & 9 deletions contrib/pageinspect/pageinspect--1.5.sql
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,6 @@ RETURNS SETOF tid
AS 'MODULE_PATHNAME', 'brin_revmap_data'
LANGUAGE C STRICT PARALLEL SAFE;

--
-- brin_upper_data()
--
CREATE FUNCTION brin_upper_data(IN page bytea,
OUT pages tid)
RETURNS SETOF tid
AS 'MODULE_PATHNAME', 'brin_upper_data'
LANGUAGE C STRICT PARALLEL SAFE;

--
-- brin_page_items()
--
Expand Down
7 changes: 2 additions & 5 deletions src/backend/access/brin/brin.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
*/
if (!brin_doupdate(idxRel, pagesPerRange, revmap, heapBlk,
buf, off, origtup, origsz, newtup, newsz,
samepage, false))
samepage))
{
/* no luck; start over */
MemoryContextResetAndDeleteChildren(tupcxt);
Expand Down Expand Up @@ -907,9 +907,6 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)

UnlockReleaseBuffer(meta);

if (isAo)
brin_init_upper_pages(index, BrinGetPagesPerRange(index));

/*
* Initialize our state, including the deformed tuple state.
*/
Expand Down Expand Up @@ -1521,7 +1518,7 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
didupdate =
brin_doupdate(state->bs_irel, state->bs_pagesPerRange,
state->bs_rmAccess, heapBlk, phbuf, offset,
phtup, phsz, newtup, newsize, samepage, false);
phtup, phsz, newtup, newsize, samepage);
brin_free_tuple(phtup);
brin_free_tuple(newtup);

Expand Down
11 changes: 4 additions & 7 deletions src/backend/access/brin/brin_pageops.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
Buffer oldbuf, OffsetNumber oldoff,
const BrinTuple *origtup, Size origsz,
const BrinTuple *newtup, Size newsz,
bool samepage, bool skipextend)
bool samepage)
{
Page oldpage;
ItemId oldlp;
Expand All @@ -78,9 +78,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
return false; /* keep compiler quiet */
}

/* make sure the revmap is long enough to contain the entry we need */
if (!skipextend)
brinRevmapExtend(revmap, heapBlk);
brinRevmapExtend(revmap, heapBlk);

if (!samepage)
{
Expand Down Expand Up @@ -596,7 +594,7 @@ brin_evacuate_page(Relation idxRel, BlockNumber pagesPerRange,
LockBuffer(buf, BUFFER_LOCK_UNLOCK);

if (!brin_doupdate(idxRel, pagesPerRange, revmap, tup->bt_blkno,
buf, off, tup, sz, tup, sz, false, true))
buf, off, tup, sz, tup, sz, false))
off--; /* retry */

LockBuffer(buf, BUFFER_LOCK_SHARE);
Expand Down Expand Up @@ -655,8 +653,7 @@ brin_page_cleanup(Relation idxrel, Buffer buf)

/* Nothing to be done for non-regular index pages */
if (BRIN_IS_META_PAGE(BufferGetPage(buf)) ||
BRIN_IS_REVMAP_PAGE(BufferGetPage(buf)) ||
BRIN_IS_UPPER_PAGE(BufferGetPage(buf)))
BRIN_IS_REVMAP_PAGE(BufferGetPage(buf)))
return;

/* Measure free space and record it */
Expand Down
167 changes: 7 additions & 160 deletions src/backend/access/brin/brin_revmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ static BlockNumber revmap_get_blkno(BrinRevmap *revmap,
static Buffer revmap_get_buffer(BrinRevmap *revmap, BlockNumber heapBlk);
static BlockNumber revmap_extend_and_get_blkno(BrinRevmap *revmap,
BlockNumber heapBlk);
static BlockNumber revmap_extend_and_get_blkno_ao(BrinRevmap *revmap,
BlockNumber heapBlk);
static BlockNumber revmap_physical_extend(BrinRevmap *revmap);

static void revmap_physical_extend(BrinRevmap *revmap);

/*
* Initialize an access object for a range map. This must be freed by
Expand Down Expand Up @@ -110,10 +107,7 @@ brinRevmapExtend(BrinRevmap *revmap, BlockNumber heapBlk)
{
BlockNumber mapBlk PG_USED_FOR_ASSERTS_ONLY;

if (revmap->rm_isAo)
mapBlk = revmap_extend_and_get_blkno_ao(revmap, heapBlk);
else
mapBlk = revmap_extend_and_get_blkno(revmap, heapBlk);
mapBlk = revmap_extend_and_get_blkno(revmap, heapBlk);

/* Ensure the buffer we got is in the expected range */
Assert(mapBlk != InvalidBlockNumber &&
Expand Down Expand Up @@ -460,30 +454,6 @@ revmap_get_blkno_heap(BrinRevmap *revmap, BlockNumber heapBlk)
return InvalidBlockNumber;
}

static BlockNumber
revmap_get_blkno_ao(BrinRevmap *revmap, BlockNumber heapBlk)
{
BlockNumber targetblk;
BlockNumber targetupperblk;
BlockNumber targetupperidx;
Buffer upperbuf;
RevmapUpperBlockContents *contents;
BlockNumber *blks;

targetupperblk = HEAPBLK_TO_REVMAP_UPPER_BLK(revmap->rm_pagesPerRange, heapBlk) + 1;
targetupperidx = HEAPBLK_TO_REVMAP_UPPER_IDX(revmap->rm_pagesPerRange, heapBlk);
upperbuf = ReadBuffer(revmap->rm_irel, targetupperblk);
contents = (RevmapUpperBlockContents*) PageGetContents(BufferGetPage(upperbuf));
blks = (BlockNumber*) contents->rm_blocks;
targetblk = blks[targetupperidx];
ReleaseBuffer(upperbuf);

if (targetblk == 0)
return InvalidBlockNumber;

return targetblk;
}

/*
* Given a heap block number, find the corresponding physical revmap block
* number and return it. If the revmap page hasn't been allocated yet, return
Expand All @@ -493,7 +463,7 @@ static BlockNumber
revmap_get_blkno(BrinRevmap *revmap, BlockNumber heapBlk)
{
if (revmap->rm_isAo)
return revmap_get_blkno_ao(revmap, heapBlk);
return -1;
else
return revmap_get_blkno_heap(revmap, heapBlk);
}
Expand Down Expand Up @@ -559,76 +529,11 @@ revmap_extend_and_get_blkno(BrinRevmap *revmap, BlockNumber heapBlk)
return targetblk;
}

/*
* Given a heap block number, find the corresponding physical revmap block
* number and return it. If the revmap page hasn't been allocated yet, extend
* the revmap until it is.
*
* This is the function called in brin on ao/cs table.
*/
static BlockNumber
revmap_extend_and_get_blkno_ao(BrinRevmap *revmap, BlockNumber heapBlk)
{
BlockNumber targetupperblk;
BlockNumber targetupperindex;
Buffer upperbuffer;
RevmapUpperBlockContents *contents;
BlockNumber *blks;
BlockNumber oldBlk;
BlockNumber newBlk;

targetupperblk = HEAPBLK_TO_REVMAP_UPPER_BLK(revmap->rm_pagesPerRange, heapBlk) + 1;
targetupperindex = HEAPBLK_TO_REVMAP_UPPER_IDX(revmap->rm_pagesPerRange, heapBlk);
upperbuffer = ReadBuffer(revmap->rm_irel, targetupperblk);

LockBuffer(upperbuffer, BUFFER_LOCK_EXCLUSIVE);
contents = (RevmapUpperBlockContents*) PageGetContents(BufferGetPage(upperbuffer));
blks = (BlockNumber*) contents->rm_blocks;
oldBlk = blks[targetupperindex];
if (oldBlk == 0)
{
CHECK_FOR_INTERRUPTS();
newBlk = InvalidBlockNumber;
while (newBlk == InvalidBlockNumber)
{
newBlk = revmap_physical_extend(revmap);
}
Assert(newBlk > revmap->rm_lastRevmapPage);
revmap->rm_lastRevmapPage = newBlk;

blks[targetupperindex] = revmap->rm_lastRevmapPage;
MarkBufferDirty(upperbuffer);

if (RelationNeedsWAL(revmap->rm_irel))
{
xl_brin_revmap_extend_upper xlrec;
XLogRecPtr recptr;

xlrec.heapBlk = heapBlk;
xlrec.pagesPerRange = revmap->rm_pagesPerRange;
xlrec.revmapBlk = revmap->rm_lastRevmapPage;
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, SizeOfBrinRevmapExtendUpper);
XLogRegisterBuffer(0, upperbuffer, 0);
recptr = XLogInsert(RM_BRIN_ID, XLOG_BRIN_REVMAP_EXTEND_UPPER);
PageSetLSN(BufferGetPage(upperbuffer), recptr);
}

UnlockReleaseBuffer(upperbuffer);
return revmap->rm_lastRevmapPage;
}
else
{
UnlockReleaseBuffer(upperbuffer);
return oldBlk;
}
}

/*
* Try to extend the revmap by one page. This might not happen for a number of
* reasons; caller is expected to retry until the expected outcome is obtained.
*/
static BlockNumber
static void
revmap_physical_extend(BrinRevmap *revmap)
{
Buffer buf;
Expand Down Expand Up @@ -657,7 +562,7 @@ revmap_physical_extend(BrinRevmap *revmap)
{
revmap->rm_lastRevmapPage = metadata->lastRevmapPage;
LockBuffer(revmap->rm_metaBuf, BUFFER_LOCK_UNLOCK);
return InvalidBlockNumber;
return;
}
mapBlk = metadata->lastRevmapPage + 1;

Expand Down Expand Up @@ -686,7 +591,7 @@ revmap_physical_extend(BrinRevmap *revmap)
UnlockRelationForExtension(irel, ExclusiveLock);
LockBuffer(revmap->rm_metaBuf, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buf);
return InvalidBlockNumber;
return;
}
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
page = BufferGetPage(buf);
Expand All @@ -711,7 +616,7 @@ revmap_physical_extend(BrinRevmap *revmap)
brin_evacuate_page(irel, revmap->rm_pagesPerRange, revmap, buf);

/* have caller start over */
return InvalidBlockNumber;
return;
}

/*
Expand Down Expand Up @@ -761,64 +666,6 @@ revmap_physical_extend(BrinRevmap *revmap)
LockBuffer(revmap->rm_metaBuf, BUFFER_LOCK_UNLOCK);

UnlockReleaseBuffer(buf);

return mapBlk;
}

/*
* When we build a brin in ao/aocs table, brin has a upper level. All the
* blocks used in upper level will be initialized once.
*/
void
brin_init_upper_pages(Relation index, BlockNumber pagesPerRange)
{
Buffer buf;
Page page;
Buffer metaBuf;
Page metaPage;
BrinMetaPageData *metadata;
int maxPage;

metaBuf = ReadBuffer(index, BRIN_METAPAGE_BLKNO);
LockBuffer(metaBuf, BUFFER_LOCK_EXCLUSIVE);
metaPage = BufferGetPage(metaBuf);

maxPage = REVMAP_UPPER_PAGE_TOTAL_NUM(pagesPerRange);
for (BlockNumber page_index = 1;
page_index <= maxPage;
++page_index)
{
buf = ReadBuffer(index, P_NEW);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);

brin_page_init(BufferGetPage(buf), BRIN_PAGETYPE_UPPER);

MarkBufferDirty(buf);

metadata = (BrinMetaPageData *) PageGetContents(metaPage);
metadata->lastRevmapPage = page_index;

if (RelationNeedsWAL(index))
{
xl_brin_createupperblk xlrec;
XLogRecPtr recptr;

xlrec.targetBlk = page_index;
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, SizeOfBrinCreateUpperBlk);
XLogRegisterBuffer(0, metaBuf, 0);
XLogRegisterBuffer(1, buf, REGBUF_WILL_INIT);
recptr = XLogInsert(RM_BRIN_ID, XLOG_BRIN_REVMAP_INIT_UPPER_BLK);

page = BufferGetPage(buf);
PageSetLSN(metaPage, recptr);
PageSetLSN(page, recptr);
}

UnlockReleaseBuffer(buf);
}

UnlockReleaseBuffer(metaBuf);
}

/*
Expand Down
Loading

0 comments on commit 3abbf94

Please sign in to comment.