From a540a042ffb0b348254afdfdce39199900f9c7ec Mon Sep 17 00:00:00 2001 From: Mircea Cadariu Date: Thu, 20 Feb 2025 13:45:12 +0000 Subject: [PATCH v1] Preliminary work to capture and expose separate record (leaf page) and metadata (non-leaf page) index access statistics in the system views, with partial coverage of B-Trees. --- contrib/amcheck/verify_heapam.c | 2 +- contrib/amcheck/verify_nbtree.c | 6 +- contrib/bloom/blinsert.c | 6 +- contrib/bloom/blscan.c | 2 +- contrib/bloom/blutils.c | 6 +- contrib/bloom/blvacuum.c | 6 +- contrib/pageinspect/btreefuncs.c | 8 +- contrib/pageinspect/rawpage.c | 2 +- contrib/pg_prewarm/autoprewarm.c | 2 +- contrib/pg_surgery/heap_surgery.c | 2 +- contrib/pg_visibility/pg_visibility.c | 2 +- contrib/pgstattuple/pgstatapprox.c | 2 +- contrib/pgstattuple/pgstatindex.c | 10 +- contrib/pgstattuple/pgstattuple.c | 10 +- doc/src/sgml/monitoring.sgml | 110 +++++++++++++++++++ src/backend/access/brin/brin.c | 4 +- src/backend/access/brin/brin_pageops.c | 4 +- src/backend/access/brin/brin_revmap.c | 12 +- src/backend/access/gin/ginbtree.c | 11 +- src/backend/access/gin/ginfast.c | 14 +-- src/backend/access/gin/ginget.c | 6 +- src/backend/access/gin/ginutil.c | 6 +- src/backend/access/gin/ginvacuum.c | 22 ++-- src/backend/access/gist/gist.c | 10 +- src/backend/access/gist/gistbuild.c | 10 +- src/backend/access/gist/gistget.c | 4 +- src/backend/access/gist/gistutil.c | 2 +- src/backend/access/gist/gistvacuum.c | 6 +- src/backend/access/hash/hash.c | 3 +- src/backend/access/hash/hashpage.c | 10 +- src/backend/access/heap/heapam.c | 16 +-- src/backend/access/heap/heapam_handler.c | 9 +- src/backend/access/heap/hio.c | 8 +- src/backend/access/heap/vacuumlazy.c | 2 +- src/backend/access/heap/visibilitymap.c | 2 +- src/backend/access/nbtree/nbtinsert.c | 32 ++++-- src/backend/access/nbtree/nbtpage.c | 65 +++++++---- src/backend/access/nbtree/nbtree.c | 2 +- src/backend/access/nbtree/nbtsearch.c | 34 ++++-- src/backend/access/nbtree/nbtutils.c | 5 +- src/backend/access/spgist/spgdoinsert.c | 4 +- src/backend/access/spgist/spgscan.c | 4 +- src/backend/access/spgist/spgutils.c | 8 +- src/backend/access/spgist/spgvacuum.c | 4 +- src/backend/access/transam/xloginsert.c | 2 +- src/backend/catalog/system_views.sql | 30 ++++- src/backend/commands/sequence.c | 2 +- src/backend/storage/aio/read_stream.c | 6 +- src/backend/storage/buffer/bufmgr.c | 52 +++++---- src/backend/storage/freespace/freespace.c | 2 +- src/backend/utils/activity/pgstat_database.c | 4 + src/backend/utils/activity/pgstat_relation.c | 8 ++ src/backend/utils/adt/pgstatfuncs.c | 24 ++++ src/include/access/nbtree.h | 4 +- src/include/catalog/pg_proc.dat | 32 ++++++ src/include/pgstat.h | 45 ++++++++ src/include/storage/bufmgr.h | 12 +- src/test/regress/expected/rules.out | 40 ++++++- 58 files changed, 557 insertions(+), 201 deletions(-) diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 827312306f..5b611b15e8 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -439,7 +439,7 @@ verify_heapam(PG_FUNCTION_ARGS) /* Read and lock the next page. */ ctx.buffer = ReadBufferExtended(ctx.rel, MAIN_FORKNUM, ctx.blkno, - RBM_NORMAL, ctx.bstrategy); + RBM_NORMAL, ctx.bstrategy, NULL); LockBuffer(ctx.buffer, BUFFER_LOCK_SHARE); ctx.page = BufferGetPage(ctx.buffer); diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index aac8c74f54..5a045b1d88 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -1249,7 +1249,7 @@ bt_recheck_sibling_links(BtreeCheckState *state, /* Couple locks in the usual order for nbtree: Left to right */ lbuf = ReadBufferExtended(state->rel, MAIN_FORKNUM, leftcurrent, - RBM_NORMAL, state->checkstrategy); + RBM_NORMAL, state->checkstrategy, NULL); LockBuffer(lbuf, BT_READ); _bt_checkpage(state->rel, lbuf); page = BufferGetPage(lbuf); @@ -1273,7 +1273,7 @@ bt_recheck_sibling_links(BtreeCheckState *state, { newtargetbuf = ReadBufferExtended(state->rel, MAIN_FORKNUM, newtargetblock, RBM_NORMAL, - state->checkstrategy); + state->checkstrategy, NULL); LockBuffer(newtargetbuf, BT_READ); _bt_checkpage(state->rel, newtargetbuf); page = BufferGetPage(newtargetbuf); @@ -3440,7 +3440,7 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) * longer than we must. */ buffer = ReadBufferExtended(state->rel, MAIN_FORKNUM, blocknum, RBM_NORMAL, - state->checkstrategy); + state->checkstrategy, NULL); LockBuffer(buffer, BT_READ); /* diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c index ee8ebaf3ca..16bf039d7b 100644 --- a/contrib/bloom/blinsert.c +++ b/contrib/bloom/blinsert.c @@ -201,7 +201,7 @@ blinsert(Relation index, Datum *values, bool *isnull, * At first, try to insert new tuple to the first page in notFullPage * array. If successful, we don't need to modify the meta page. */ - metaBuffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO); + metaBuffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO, NULL); LockBuffer(metaBuffer, BUFFER_LOCK_SHARE); metaData = BloomPageGetMeta(BufferGetPage(metaBuffer)); @@ -213,7 +213,7 @@ blinsert(Relation index, Datum *values, bool *isnull, /* Don't hold metabuffer lock while doing insert */ LockBuffer(metaBuffer, BUFFER_LOCK_UNLOCK); - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); state = GenericXLogStart(index); @@ -280,7 +280,7 @@ blinsert(Relation index, Datum *values, bool *isnull, blkno = metaData->notFullPage[nStart]; Assert(blkno != InvalidBlockNumber); - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); page = GenericXLogRegisterBuffer(state, buffer, 0); diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c index bf801fe78f..30714944ac 100644 --- a/contrib/bloom/blscan.c +++ b/contrib/bloom/blscan.c @@ -123,7 +123,7 @@ blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) Page page; buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, - blkno, RBM_NORMAL, bas); + blkno, RBM_NORMAL, bas, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 04b61042a5..e73fe580ce 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -185,7 +185,7 @@ initBloomState(BloomState *state, Relation index) opts = MemoryContextAlloc(index->rd_indexcxt, sizeof(BloomOptions)); - buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO); + buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); @@ -364,7 +364,7 @@ BloomNewBuffer(Relation index) if (blkno == InvalidBlockNumber) break; - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); /* * We have to guard against the possibility that someone else already @@ -456,7 +456,7 @@ BloomInitMetapage(Relation index, ForkNumber forknum) * block number 0 (BLOOM_METAPAGE_BLKNO). No need to hold the extension * lock because there cannot be concurrent inserters yet. */ - metaBuffer = ReadBufferExtended(index, forknum, P_NEW, RBM_NORMAL, NULL); + metaBuffer = ReadBufferExtended(index, forknum, P_NEW, RBM_NORMAL, NULL, NULL); LockBuffer(metaBuffer, BUFFER_LOCK_EXCLUSIVE); Assert(BufferGetBlockNumber(metaBuffer) == BLOOM_METAPAGE_BLKNO); diff --git a/contrib/bloom/blvacuum.c b/contrib/bloom/blvacuum.c index 86b15a75f6..ebe769d375 100644 --- a/contrib/bloom/blvacuum.c +++ b/contrib/bloom/blvacuum.c @@ -60,7 +60,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, vacuum_delay_point(false); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); gxlogState = GenericXLogStart(index); @@ -139,7 +139,7 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, * info could already be out of date at this point, but blinsert() will * cope if so. */ - buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO); + buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); gxlogState = GenericXLogStart(index); @@ -190,7 +190,7 @@ blvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) vacuum_delay_point(false); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = (Page) BufferGetPage(buffer); diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index 9cdc8e182b..e7c3bf2f78 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -282,7 +282,7 @@ bt_page_stats_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version) bt_index_block_validate(rel, blkno); - buffer = ReadBuffer(rel, blkno); + buffer = ReadBuffer(rel, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); /* keep compiler quiet */ @@ -422,7 +422,7 @@ bt_multi_page_stats(PG_FUNCTION_ARGS) BTPageStat stat; TupleDesc tupleDesc; - buffer = ReadBuffer(rel, uargs->blkno); + buffer = ReadBuffer(rel, uargs->blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); /* keep compiler quiet */ @@ -651,7 +651,7 @@ bt_page_items_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version) bt_index_block_validate(rel, blkno); - buffer = ReadBuffer(rel, blkno); + buffer = ReadBuffer(rel, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); /* @@ -875,7 +875,7 @@ bt_metap(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); - buffer = ReadBuffer(rel, 0); + buffer = ReadBuffer(rel, 0, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 617dff821a..7605326c66 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -185,7 +185,7 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno) /* Take a verbatim copy of the page */ - buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL); + buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL, NULL); LockBuffer(buf, BUFFER_LOCK_SHARE); memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ); diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index b45755b334..df335a054a 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -533,7 +533,7 @@ autoprewarm_database_main(Datum main_arg) /* Prewarm buffer. */ buf = ReadBufferExtended(rel, blk->forknum, blk->blocknum, RBM_NORMAL, - NULL); + NULL, NULL); if (BufferIsValid(buf)) { apw_state->prewarmed_blocks++; diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index 5b94b3d523..62388c6175 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -172,7 +172,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) continue; } - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, NULL); LockBufferForCleanup(buf); page = BufferGetPage(buf); diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index 7f268a18a7..a11469660d 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -151,7 +151,7 @@ pg_visibility(PG_FUNCTION_ARGS) /* Here we have to explicitly check rel size ... */ if (blkno < RelationGetNumberOfBlocks(rel)) { - buffer = ReadBuffer(rel, blkno); + buffer = ReadBuffer(rel, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c index a59ff4e9d4..46efc49522 100644 --- a/contrib/pgstattuple/pgstatapprox.c +++ b/contrib/pgstattuple/pgstatapprox.c @@ -94,7 +94,7 @@ statapprox_heap(Relation rel, output_type *stat) } buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, - RBM_NORMAL, bstrategy); + RBM_NORMAL, bstrategy, NULL); LockBuffer(buf, BUFFER_LOCK_SHARE); diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index 4b9d76ec4e..a0a924acbf 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -250,7 +250,8 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo) * Read metapage */ { - Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy); + Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, + bstrategy, NULL); Page page = BufferGetPage(buffer); BTMetaPageData *metad = BTPageGetMeta(page); @@ -286,7 +287,8 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); /* Read and lock buffer */ - buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); + buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, + bstrategy, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); @@ -542,7 +544,7 @@ pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo) /* * Read metapage */ - buffer = ReadBuffer(rel, GIN_METAPAGE_BLKNO); + buffer = ReadBuffer(rel, GIN_METAPAGE_BLKNO, NULL); LockBuffer(buffer, GIN_SHARE); page = BufferGetPage(buffer); metadata = GinPageGetMeta(page); @@ -645,7 +647,7 @@ pgstathashindex(PG_FUNCTION_ARGS) CHECK_FOR_INTERRUPTS(); buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - bstrategy); + bstrategy, NULL); LockBuffer(buf, BUFFER_LOCK_SHARE); page = (Page) BufferGetPage(buf); diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index 48cb8f59c4..a15668dc11 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -373,7 +373,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, - RBM_NORMAL, hscan->rs_strategy); + RBM_NORMAL, hscan->rs_strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetExactFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); @@ -386,7 +386,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, - RBM_NORMAL, hscan->rs_strategy); + RBM_NORMAL, hscan->rs_strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetExactFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); @@ -411,7 +411,8 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, Buffer buf; Page page; - buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); + buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy, + NULL); LockBuffer(buf, BT_READ); page = BufferGetPage(buf); @@ -497,7 +498,8 @@ pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, Buffer buf; Page page; - buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); + buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy, + NULL); LockBuffer(buf, GIST_SHARE); gistcheckpage(rel, buf); page = BufferGetPage(buf); diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 71c4f96d05..e3d1477ef0 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -3425,6 +3425,44 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + metadata_blks_read bigint + + + Number of metadata disk blocks read in this database + + + + + + metadata_blks_hit bigint + + + Number of times metadata disk blocks were found already in the buffer + cache + + + + + + record_blks_read bigint + + + Number of record disk blocks read in this database + + + + + + record_blks_hit bigint + + + Number of times record disk blocks were found already in the buffer + cache + + + blks_hit bigint @@ -4368,6 +4406,42 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + idx_metadata_blks_read bigint + + + Number of metadata disk blocks read from all indexes on this table + + + + + + idx_metadata_blks_hit bigint + + + Number of metadata block hits in all indexes on this table + + + + + + idx_record_blks_read bigint + + + Number of record disk blocks read from all indexes on this table + + + + + + idx_record_blks_hit bigint + + + Number of record block hits in all indexes on this table + + + idx_blks_hit bigint @@ -4504,6 +4578,42 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + idx_metadata_blks_read bigint + + + Number of metadata disk blocks read from this index + + + + + + idx_metadata_blks_hit bigint + + + Number of metadata buffer hits in this index + + + + + + idx_record_blks_read bigint + + + Number of record disk blocks read from this index + + + + + + idx_record_blks_hit bigint + + + Number of record buffer hits in this index + + + idx_blks_hit bigint diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 60320440fc..5c0e3febe5 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1647,7 +1647,7 @@ brinGetStats(Relation index, BrinStatsData *stats) Page metapage; BrinMetaPageData *metadata; - metabuffer = ReadBuffer(index, BRIN_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, BRIN_METAPAGE_BLKNO, NULL); LockBuffer(metabuffer, BUFFER_LOCK_SHARE); metapage = BufferGetPage(metabuffer); metadata = (BrinMetaPageData *) PageGetContents(metapage); @@ -2182,7 +2182,7 @@ brin_vacuum_scan(Relation idxrel, BufferAccessStrategy strategy) CHECK_FOR_INTERRUPTS(); buf = ReadBufferExtended(idxrel, MAIN_FORKNUM, blkno, - RBM_NORMAL, strategy); + RBM_NORMAL, strategy, NULL); brin_page_cleanup(idxrel, buf); diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c index 6d8dd1512d..c78f0cc4e7 100644 --- a/src/backend/access/brin/brin_pageops.c +++ b/src/backend/access/brin/brin_pageops.c @@ -739,7 +739,7 @@ brin_getinsertbuffer(Relation irel, Buffer oldbuf, Size itemsz, LockRelationForExtension(irel, ExclusiveLock); extensionLockHeld = true; } - buf = ReadBuffer(irel, P_NEW); + buf = ReadBuffer(irel, P_NEW, NULL); newblk = BufferGetBlockNumber(buf); *extended = true; @@ -756,7 +756,7 @@ brin_getinsertbuffer(Relation irel, Buffer oldbuf, Size itemsz, } else { - buf = ReadBuffer(irel, newblk); + buf = ReadBuffer(irel, newblk, NULL); } /* diff --git a/src/backend/access/brin/brin_revmap.c b/src/backend/access/brin/brin_revmap.c index 4e380ecc71..4a0256d96a 100644 --- a/src/backend/access/brin/brin_revmap.c +++ b/src/backend/access/brin/brin_revmap.c @@ -74,7 +74,7 @@ brinRevmapInitialize(Relation idxrel, BlockNumber *pagesPerRange) BrinMetaPageData *metadata; Page page; - meta = ReadBuffer(idxrel, BRIN_METAPAGE_BLKNO); + meta = ReadBuffer(idxrel, BRIN_METAPAGE_BLKNO, NULL); LockBuffer(meta, BUFFER_LOCK_SHARE); page = BufferGetPage(meta); metadata = (BrinMetaPageData *) PageGetContents(page); @@ -231,7 +231,7 @@ brinGetTupleForHeapBlock(BrinRevmap *revmap, BlockNumber heapBlk, ReleaseBuffer(revmap->rm_currBuf); Assert(mapBlk != InvalidBlockNumber); - revmap->rm_currBuf = ReadBuffer(revmap->rm_irel, mapBlk); + revmap->rm_currBuf = ReadBuffer(revmap->rm_irel, mapBlk, NULL); } LockBuffer(revmap->rm_currBuf, BUFFER_LOCK_SHARE); @@ -269,7 +269,7 @@ brinGetTupleForHeapBlock(BrinRevmap *revmap, BlockNumber heapBlk, { if (BufferIsValid(*buf)) ReleaseBuffer(*buf); - *buf = ReadBuffer(idxRel, blk); + *buf = ReadBuffer(idxRel, blk, NULL); } LockBuffer(*buf, mode); page = BufferGetPage(*buf); @@ -363,7 +363,7 @@ brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk) return true; } - regBuf = ReadBuffer(idxrel, ItemPointerGetBlockNumber(iptr)); + regBuf = ReadBuffer(idxrel, ItemPointerGetBlockNumber(iptr), NULL); LockBuffer(regBuf, BUFFER_LOCK_EXCLUSIVE); regPg = BufferGetPage(regBuf); @@ -485,7 +485,7 @@ revmap_get_buffer(BrinRevmap *revmap, BlockNumber heapBlk) if (revmap->rm_currBuf != InvalidBuffer) ReleaseBuffer(revmap->rm_currBuf); - revmap->rm_currBuf = ReadBuffer(revmap->rm_irel, mapBlk); + revmap->rm_currBuf = ReadBuffer(revmap->rm_irel, mapBlk, NULL); } return revmap->rm_currBuf; @@ -553,7 +553,7 @@ revmap_physical_extend(BrinRevmap *revmap) nblocks = RelationGetNumberOfBlocks(irel); if (mapBlk < nblocks) { - buf = ReadBuffer(irel, mapBlk); + buf = ReadBuffer(irel, mapBlk, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); page = BufferGetPage(buf); } diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c index 26a0bdc206..ee04a27528 100644 --- a/src/backend/access/gin/ginbtree.c +++ b/src/backend/access/gin/ginbtree.c @@ -87,7 +87,7 @@ ginFindLeafPage(GinBtree btree, bool searchMode, stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack)); stack->blkno = btree->rootBlkno; - stack->buffer = ReadBuffer(btree->index, btree->rootBlkno); + stack->buffer = ReadBuffer(btree->index, btree->rootBlkno, NULL); stack->parent = NULL; stack->predictNumber = 1; @@ -148,7 +148,8 @@ ginFindLeafPage(GinBtree btree, bool searchMode, { /* in search mode we may forget path to leaf */ stack->blkno = child; - stack->buffer = ReleaseAndReadBuffer(stack->buffer, btree->index, stack->blkno); + stack->buffer = ReleaseAndReadBuffer(stack->buffer, btree->index, stack->blkno, + NULL); } else { @@ -157,7 +158,7 @@ ginFindLeafPage(GinBtree btree, bool searchMode, ptr->parent = stack; stack = ptr; stack->blkno = child; - stack->buffer = ReadBuffer(btree->index, stack->blkno); + stack->buffer = ReadBuffer(btree->index, stack->blkno, NULL); stack->predictNumber = 1; } } @@ -182,7 +183,7 @@ ginStepRight(Buffer buffer, Relation index, int lockmode) bool isData = GinPageIsData(page); BlockNumber blkno = GinPageGetOpaque(page)->rightlink; - nextbuffer = ReadBuffer(index, blkno); + nextbuffer = ReadBuffer(index, blkno, NULL); LockBuffer(nextbuffer, lockmode); UnlockReleaseBuffer(buffer); @@ -314,7 +315,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack) /* Descend down to next level */ blkno = leftmostBlkno; - buffer = ReadBuffer(btree->index, blkno); + buffer = ReadBuffer(btree->index, blkno, NULL); } } diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index a6d88572cc..68e5112732 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -239,7 +239,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector) data.ntuples = 0; data.newRightlink = data.prevTail = InvalidBlockNumber; - metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO, NULL); metapage = BufferGetPage(metabuffer); /* @@ -319,7 +319,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector) data.prevTail = metadata->tail; data.newRightlink = sublist.head; - buffer = ReadBuffer(index, metadata->tail); + buffer = ReadBuffer(index, metadata->tail, NULL); LockBuffer(buffer, GIN_EXCLUSIVE); page = BufferGetPage(buffer); @@ -358,7 +358,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector) CheckForSerializableConflictIn(index, NULL, GIN_METAPAGE_BLKNO); - buffer = ReadBuffer(index, metadata->tail); + buffer = ReadBuffer(index, metadata->tail, NULL); LockBuffer(buffer, GIN_EXCLUSIVE); page = BufferGetPage(buffer); @@ -575,7 +575,7 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead, while (data.ndeleted < GIN_NDELETE_AT_ONCE && blknoToDelete != newHead) { freespace[data.ndeleted] = blknoToDelete; - buffers[data.ndeleted] = ReadBuffer(index, blknoToDelete); + buffers[data.ndeleted] = ReadBuffer(index, blknoToDelete, NULL); LockBuffer(buffers[data.ndeleted], GIN_EXCLUSIVE); page = BufferGetPage(buffers[data.ndeleted]); @@ -827,7 +827,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, workMemory = work_mem; } - metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO, NULL); LockBuffer(metabuffer, GIN_SHARE); metapage = BufferGetPage(metabuffer); metadata = GinPageGetMeta(metapage); @@ -850,7 +850,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, * Read and lock head of pending list */ blkno = metadata->head; - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, GIN_SHARE); page = BufferGetPage(buffer); @@ -1003,7 +1003,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, * Read next page in pending list */ vacuum_delay_point(false); - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, GIN_SHARE); page = BufferGetPage(buffer); } diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 63dd1f3679..ebcab38baf 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -1480,7 +1480,7 @@ scanGetCandidate(IndexScanDesc scan, pendingPosition *pos) * current page. So, we lock next page before releasing the * current one */ - Buffer tmpbuf = ReadBuffer(scan->indexRelation, blkno); + Buffer tmpbuf = ReadBuffer(scan->indexRelation, blkno, NULL); LockBuffer(tmpbuf, GIN_SHARE); UnlockReleaseBuffer(pos->pendingBuffer); @@ -1827,7 +1827,7 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) match; int i; pendingPosition pos; - Buffer metabuffer = ReadBuffer(scan->indexRelation, GIN_METAPAGE_BLKNO); + Buffer metabuffer = ReadBuffer(scan->indexRelation, GIN_METAPAGE_BLKNO, NULL); Page page; BlockNumber blkno; @@ -1854,7 +1854,7 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) return; } - pos.pendingBuffer = ReadBuffer(scan->indexRelation, blkno); + pos.pendingBuffer = ReadBuffer(scan->indexRelation, blkno, NULL); LockBuffer(pos.pendingBuffer, GIN_SHARE); pos.firstOffset = FirstOffsetNumber; UnlockReleaseBuffer(metabuffer); diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 1f9e58c4f1..c12b44eaca 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -310,7 +310,7 @@ GinNewBuffer(Relation index) if (blkno == InvalidBlockNumber) break; - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); /* * We have to guard against the possibility that someone else already @@ -627,7 +627,7 @@ ginGetStats(Relation index, GinStatsData *stats) Page metapage; GinMetaPageData *metadata; - metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO, NULL); LockBuffer(metabuffer, GIN_SHARE); metapage = BufferGetPage(metabuffer); metadata = GinPageGetMeta(metapage); @@ -654,7 +654,7 @@ ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build) Page metapage; GinMetaPageData *metadata; - metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO, NULL); LockBuffer(metabuffer, GIN_EXCLUSIVE); metapage = BufferGetPage(metabuffer); metadata = GinPageGetMeta(metapage); diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index fbbe3a6dd7..250bffa49a 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -143,11 +143,11 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn * deletable, parent and left pages. */ lBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, leftBlkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); dBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, deleteBlkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); pBuffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, parentBlkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); page = BufferGetPage(dBuffer); rightlink = GinPageGetOpaque(page)->rightlink; @@ -270,7 +270,7 @@ ginScanToDelete(GinVacuumState *gvs, BlockNumber blkno, bool isRoot, } buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); if (!isRoot) LockBuffer(buffer, GIN_EXCLUSIVE); @@ -355,7 +355,7 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) PostingItem *pitem; buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); LockBuffer(buffer, GIN_SHARE); page = BufferGetPage(buffer); @@ -396,7 +396,7 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) break; buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); LockBuffer(buffer, GIN_EXCLUSIVE); page = BufferGetPage(buffer); } @@ -419,7 +419,7 @@ ginVacuumPostingTree(GinVacuumState *gvs, BlockNumber rootBlkno) *tmp; buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, rootBlkno, - RBM_NORMAL, gvs->strategy); + RBM_NORMAL, gvs->strategy, NULL); /* * Lock posting tree root for cleanup to ensure there are no @@ -598,7 +598,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, gvs.result = stats; buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); /* find leaf page */ for (;;) @@ -631,7 +631,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, UnlockReleaseBuffer(buffer); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); } /* right now we found leftmost page in entry's BTree */ @@ -674,7 +674,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, break; buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(buffer, GIN_EXCLUSIVE); } @@ -751,7 +751,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) vacuum_delay_point(false); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(buffer, GIN_SHARE); page = (Page) BufferGetPage(buffer); diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 4d858b65e1..d393f0c731 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -681,7 +681,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, } if (XLogRecPtrIsInvalid(stack->lsn)) - stack->buffer = ReadBuffer(state.r, stack->blkno); + stack->buffer = ReadBuffer(state.r, stack->blkno, NULL); /* * Be optimistic and grab shared lock first. Swap it for an exclusive @@ -932,7 +932,7 @@ gistFindPath(Relation r, BlockNumber child, OffsetNumber *downlinkoffnum) top = linitial(fifo); fifo = list_delete_first(fifo); - buffer = ReadBuffer(r, top->blkno); + buffer = ReadBuffer(r, top->blkno, NULL); LockBuffer(buffer, GIST_SHARE); gistcheckpage(r, buffer); page = (Page) BufferGetPage(buffer); @@ -1085,7 +1085,7 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child, bool is_build) */ break; } - parent->buffer = ReadBuffer(r, parent->blkno); + parent->buffer = ReadBuffer(r, parent->blkno, NULL); LockBuffer(parent->buffer, GIST_EXCLUSIVE); gistcheckpage(r, parent->buffer); parent->page = (Page) BufferGetPage(parent->buffer); @@ -1110,7 +1110,7 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child, bool is_build) /* note we don't lock them or gistcheckpage them here! */ while (ptr) { - ptr->buffer = ReadBuffer(r, ptr->blkno); + ptr->buffer = ReadBuffer(r, ptr->blkno, NULL); ptr->page = (Page) BufferGetPage(ptr->buffer); ptr = ptr->parent; } @@ -1225,7 +1225,7 @@ gistfixsplit(GISTInsertState *state, GISTSTATE *giststate) if (GistFollowRight(page)) { /* lock next page */ - buf = ReadBuffer(state->r, GistPageGetOpaque(page)->rightlink); + buf = ReadBuffer(state->r, GistPageGetOpaque(page)->rightlink, NULL); LockBuffer(buf, GIST_EXCLUSIVE); } else diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 9e707167d9..20a2310dfc 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -966,7 +966,7 @@ gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, * descend down to. */ - buffer = ReadBuffer(indexrel, blkno); + buffer = ReadBuffer(indexrel, blkno, NULL); LockBuffer(buffer, GIST_EXCLUSIVE); page = (Page) BufferGetPage(buffer); @@ -1029,7 +1029,7 @@ gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, * We've reached a leaf page. Place the tuple here. */ Assert(level == 0); - buffer = ReadBuffer(indexrel, blkno); + buffer = ReadBuffer(indexrel, blkno, NULL); LockBuffer(buffer, GIST_EXCLUSIVE); gistbufferinginserttuples(buildstate, buffer, level, &itup, 1, InvalidOffsetNumber, @@ -1102,7 +1102,7 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level, ItemId iid = PageGetItemId(page, off); IndexTuple idxtuple = (IndexTuple) PageGetItem(page, iid); BlockNumber childblkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); - Buffer childbuf = ReadBuffer(buildstate->indexrel, childblkno); + Buffer childbuf = ReadBuffer(buildstate->indexrel, childblkno, NULL); LockBuffer(childbuf, GIST_SHARE); gistMemorizeAllDownlinks(buildstate, childbuf); @@ -1246,7 +1246,7 @@ gistBufferingFindCorrectParent(GISTBuildState *buildstate, parent = *parentblkno; } - buffer = ReadBuffer(buildstate->indexrel, parent); + buffer = ReadBuffer(buildstate->indexrel, parent, NULL); page = BufferGetPage(buffer); LockBuffer(buffer, GIST_EXCLUSIVE); gistcheckpage(buildstate->indexrel, buffer); @@ -1441,7 +1441,7 @@ gistGetMaxLevel(Relation index) Page page; IndexTuple itup; - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); /* * There's no concurrent access during index build, so locking is just diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index cc40e928e0..98c9356b4b 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -49,7 +49,7 @@ gistkillitems(IndexScanDesc scan) Assert(!XLogRecPtrIsInvalid(so->curPageLSN)); Assert(so->killedItems != NULL); - buffer = ReadBuffer(scan->indexRelation, so->curBlkno); + buffer = ReadBuffer(scan->indexRelation, so->curBlkno, NULL); if (!BufferIsValid(buffer)) return; @@ -340,7 +340,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, Assert(!GISTSearchItemIsHeap(*pageItem)); - buffer = ReadBuffer(scan->indexRelation, pageItem->blkno); + buffer = ReadBuffer(scan->indexRelation, pageItem->blkno, NULL); LockBuffer(buffer, GIST_SHARE); PredicateLockPage(r, BufferGetBlockNumber(buffer), scan->xs_snapshot); gistcheckpage(scan->indexRelation, buffer); diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index dbc4ac639a..b4dcc1056f 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -833,7 +833,7 @@ gistNewBuffer(Relation r, Relation heaprel) if (blkno == InvalidBlockNumber) break; /* nothing left in FSM */ - buffer = ReadBuffer(r, blkno); + buffer = ReadBuffer(r, blkno, NULL); /* * We have to guard against the possibility that someone else already diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index dd0d9d5006..f95e42f40a 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -286,7 +286,7 @@ restart: vacuum_delay_point(false); buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - info->strategy); + info->strategy, NULL); /* * We are not going to stay here for a long time, aggressively grab an @@ -482,7 +482,7 @@ gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistVacState *vstate) int deleted; buffer = ReadBufferExtended(rel, MAIN_FORKNUM, (BlockNumber) blkno, - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(buffer, GIST_SHARE); page = (Page) BufferGetPage(buffer); @@ -548,7 +548,7 @@ gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistVacState *vstate) break; leafbuf = ReadBufferExtended(rel, MAIN_FORKNUM, leafs_to_delete[i], - RBM_NORMAL, info->strategy); + RBM_NORMAL, info->strategy, NULL); LockBuffer(leafbuf, GIST_EXCLUSIVE); gistcheckpage(rel, leafbuf); diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 02ec1126a4..c806df1eb9 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -512,7 +512,8 @@ loop_top: * We need to acquire a cleanup lock on the primary bucket page to out * wait concurrent scans before deleting the dead tuples. */ - buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, info->strategy); + buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, info->strategy, + NULL); LockBufferForCleanup(buf); _hash_checkpage(rel, buf, LH_BUCKET_PAGE); diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index b8e5bd005e..33dbcfd2f1 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -74,7 +74,7 @@ _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags) if (blkno == P_NEW) elog(ERROR, "hash AM does not use P_NEW"); - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, NULL); if (access != HASH_NOLOCK) LockBuffer(buf, access); @@ -100,7 +100,7 @@ _hash_getbuf_with_condlock_cleanup(Relation rel, BlockNumber blkno, int flags) if (blkno == P_NEW) elog(ERROR, "hash AM does not use P_NEW"); - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, NULL); if (!ConditionalLockBufferForCleanup(buf)) { @@ -140,7 +140,7 @@ _hash_getinitbuf(Relation rel, BlockNumber blkno) elog(ERROR, "hash AM does not use P_NEW"); buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_ZERO_AND_LOCK, - NULL); + NULL, NULL); /* ref count and lock type are correct */ @@ -218,7 +218,7 @@ _hash_getnewbuf(Relation rel, BlockNumber blkno, ForkNumber forkNum) else { buf = ReadBufferExtended(rel, forkNum, blkno, RBM_ZERO_AND_LOCK, - NULL); + NULL, NULL); } /* ref count and lock type are correct */ @@ -245,7 +245,7 @@ _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, if (blkno == P_NEW) elog(ERROR, "hash AM does not use P_NEW"); - buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); + buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy, NULL); if (access != HASH_NOLOCK) LockBuffer(buf, access); diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index fa7935a0ed..5a0aa9998c 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -1538,7 +1538,7 @@ heap_fetch(Relation relation, /* * Fetch and pin the appropriate page of the relation. */ - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); + buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid), NULL); /* * Need share lock on buffer to examine tuple commit status. @@ -1832,7 +1832,7 @@ heap_get_latest_tid(TableScanDesc sscan, /* * Read, pin, and lock the page. */ - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid)); + buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid), NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); @@ -2728,7 +2728,7 @@ heap_delete(Relation relation, ItemPointer tid, errmsg("cannot delete tuples during a parallel operation"))); block = ItemPointerGetBlockNumber(tid); - buffer = ReadBuffer(relation, block); + buffer = ReadBuffer(relation, block, NULL); page = BufferGetPage(buffer); /* @@ -3257,7 +3257,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, block = ItemPointerGetBlockNumber(otid); INJECTION_POINT("heap_update-before-pin"); - buffer = ReadBuffer(relation, block); + buffer = ReadBuffer(relation, block, NULL); page = BufferGetPage(buffer); /* @@ -4513,7 +4513,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, bool have_tuple_lock = false; bool cleared_all_frozen = false; - *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); + *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid), NULL); block = ItemPointerGetBlockNumber(tid); /* @@ -6009,7 +6009,7 @@ heap_finish_speculative(Relation relation, ItemPointer tid) ItemId lp = NULL; HeapTupleHeader htup; - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); + buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid), NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); page = (Page) BufferGetPage(buffer); @@ -6100,7 +6100,7 @@ heap_abort_speculative(Relation relation, ItemPointer tid) Assert(ItemPointerIsValid(tid)); block = ItemPointerGetBlockNumber(tid); - buffer = ReadBuffer(relation, block); + buffer = ReadBuffer(relation, block, NULL); page = BufferGetPage(buffer); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); @@ -8181,7 +8181,7 @@ heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate) UnlockReleaseBuffer(buf); blkno = ItemPointerGetBlockNumber(htid); - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, NULL); nblocksaccessed++; Assert(!delstate->bottomup || nblocksaccessed <= BOTTOMUP_MAX_NBLOCKS); diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index c0bec01415..12167d9bb5 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -128,7 +128,8 @@ heapam_index_fetch_tuple(struct IndexFetchTableData *scan, hscan->xs_cbuf = ReleaseAndReadBuffer(hscan->xs_cbuf, hscan->xs_base.rel, - ItemPointerGetBlockNumber(tid)); + ItemPointerGetBlockNumber(tid), + NULL); /* * Prune page, but only if we weren't already on this page @@ -2185,7 +2186,8 @@ heapam_scan_bitmap_next_block(TableScanDesc scan, */ hscan->rs_cbuf = ReleaseAndReadBuffer(hscan->rs_cbuf, scan->rs_rd, - block); + block, + NULL); hscan->rs_cblock = block; buffer = hscan->rs_cbuf; snapshot = scan->rs_snapshot; @@ -2414,7 +2416,8 @@ heapam_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate) /* Read page using selected strategy */ hscan->rs_cbuf = ReadBufferExtended(hscan->rs_base.rs_rd, MAIN_FORKNUM, - blockno, RBM_NORMAL, hscan->rs_strategy); + blockno, RBM_NORMAL, hscan->rs_strategy, + NULL); /* in pagemode, prune the page and determine visible tuple offsets */ if (hscan->rs_base.rs_flags & SO_ALLOW_PAGEMODE) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index c482c9d61b..7d5afcc6bc 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -93,7 +93,7 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock, /* If not bulk-insert, exactly like ReadBuffer */ if (!bistate) return ReadBufferExtended(relation, MAIN_FORKNUM, targetBlock, - mode, NULL); + mode, NULL, NULL); /* If we have the desired block already pinned, re-pin and return it */ if (bistate->current_buf != InvalidBuffer) @@ -117,7 +117,7 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock, /* Perform a read using the buffer strategy */ buffer = ReadBufferExtended(relation, MAIN_FORKNUM, targetBlock, - mode, bistate->strategy); + mode, bistate->strategy, NULL); /* Save the selected block as target for future inserts */ IncrBufferRefCount(buffer); @@ -640,7 +640,7 @@ loop: else if (otherBlock < targetBlock) { /* lock other buffer first */ - buffer = ReadBuffer(relation, targetBlock); + buffer = ReadBuffer(relation, targetBlock, NULL); if (PageIsAllVisible(BufferGetPage(buffer))) visibilitymap_pin(relation, targetBlock, vmbuffer); LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE); @@ -649,7 +649,7 @@ loop: else { /* lock target buffer first */ - buffer = ReadBuffer(relation, targetBlock); + buffer = ReadBuffer(relation, targetBlock, NULL); if (PageIsAllVisible(BufferGetPage(buffer))) visibilitymap_pin(relation, targetBlock, vmbuffer); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 1af18a78a2..4e63579b61 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -3394,7 +3394,7 @@ count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected) } buf = ReadBufferExtended(vacrel->rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - vacrel->bstrategy); + vacrel->bstrategy, NULL); /* In this phase we only need shared access to the buffer */ LockBuffer(buf, BUFFER_LOCK_SHARE); diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index 745a04ef26..a31f3098de 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -582,7 +582,7 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend) } else buf = ReadBufferExtended(rel, VISIBILITYMAP_FORKNUM, blkno, - RBM_ZERO_ON_ERROR, NULL); + RBM_ZERO_ON_ERROR, NULL, NULL); /* * Initializing the page when needed is trickier than it looks, because of diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 31fe1c3ade..c76f1fd2d5 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -21,6 +21,7 @@ #include "access/xloginsert.h" #include "common/int.h" #include "common/pg_prng.h" +#include "pgstat.h" #include "lib/qunique.h" #include "miscadmin.h" #include "storage/lmgr.h" @@ -323,7 +324,7 @@ _bt_search_insert(Relation rel, Relation heaprel, BTInsertState insertstate) if (RelationGetTargetBlock(rel) != InvalidBlockNumber) { /* Simulate a _bt_getbuf() call with conditional locking */ - insertstate->buf = ReadBuffer(rel, RelationGetTargetBlock(rel)); + insertstate->buf = ReadBuffer(rel, RelationGetTargetBlock(rel), NULL); if (_bt_conditionallockbuf(rel, insertstate->buf)) { Page page; @@ -733,7 +734,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel, { BlockNumber nblkno = opaque->btpo_next; - nbuf = _bt_relandgetbuf(rel, nbuf, nblkno, BT_READ); + nbuf = _bt_relandgetbuf(rel, nbuf, nblkno, BT_READ, NULL); page = BufferGetPage(nbuf); opaque = BTPageGetOpaque(page); if (!P_IGNORE(opaque)) @@ -1040,7 +1041,9 @@ _bt_stepright(Relation rel, Relation heaprel, BTInsertState insertstate, rblkno = opaque->btpo_next; for (;;) { - rbuf = _bt_relandgetbuf(rel, rbuf, rblkno, BT_WRITE); + bool hit; + rbuf = _bt_relandgetbuf(rel, rbuf, rblkno, BT_WRITE, &hit); + pgstat_count_buffer(rel, P_ISLEAF(opaque), hit); page = BufferGetPage(rbuf); opaque = BTPageGetOpaque(page); @@ -1256,10 +1259,14 @@ _bt_insertonpg(Relation rel, */ if (unlikely(split_only_page)) { + bool hit; + Assert(!isleaf); Assert(BufferIsValid(cbuf)); - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE, &hit); + pgstat_count_buffer(rel, true, hit); + metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); @@ -1890,7 +1897,9 @@ _bt_split(Relation rel, Relation heaprel, BTScanInsert itup_key, Buffer buf, */ if (!isrightmost) { - sbuf = _bt_getbuf(rel, oopaque->btpo_next, BT_WRITE); + bool hit; + sbuf = _bt_getbuf(rel, oopaque->btpo_next, BT_WRITE, &hit); + pgstat_count_buffer(rel, P_ISLEAF(oopaque), hit); spage = BufferGetPage(sbuf); sopaque = BTPageGetOpaque(spage); if (sopaque->btpo_prev != origpagenumber) @@ -2247,12 +2256,14 @@ _bt_finish_split(Relation rel, Relation heaprel, Buffer lbuf, BTStack stack) BTPageOpaque rpageop; bool wasroot; bool wasonly; + bool hit; Assert(P_INCOMPLETE_SPLIT(lpageop)); Assert(heaprel != NULL); /* Lock right sibling, the one missing the downlink */ - rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE); + rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE, &hit); + pgstat_count_buffer(rel, P_ISLEAF(lpageop), hit); rpage = BufferGetPage(rbuf); rpageop = BTPageGetOpaque(rpage); @@ -2264,7 +2275,8 @@ _bt_finish_split(Relation rel, Relation heaprel, Buffer lbuf, BTStack stack) BTMetaPageData *metad; /* acquire lock on the metapage */ - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE, &hit); + pgstat_count_buffer(rel, true, hit); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); @@ -2330,7 +2342,7 @@ _bt_getstackbuf(Relation rel, Relation heaprel, BTStack stack, BlockNumber child Page page; BTPageOpaque opaque; - buf = _bt_getbuf(rel, blkno, BT_WRITE); + buf = _bt_getbuf(rel, blkno, BT_WRITE, NULL); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); @@ -2460,6 +2472,7 @@ _bt_newlevel(Relation rel, Relation heaprel, Buffer lbuf, Buffer rbuf) Buffer metabuf; Page metapg; BTMetaPageData *metad; + bool hit; lbkno = BufferGetBlockNumber(lbuf); rbkno = BufferGetBlockNumber(rbuf); @@ -2472,7 +2485,8 @@ _bt_newlevel(Relation rel, Relation heaprel, Buffer lbuf, Buffer rbuf) rootblknum = BufferGetBlockNumber(rootbuf); /* acquire lock on the metapage */ - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE, &hit); + pgstat_count_buffer(rel, true, hit); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index c79dd38ee1..9bcb341470 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -30,6 +30,7 @@ #include "access/xloginsert.h" #include "common/int.h" #include "miscadmin.h" +#include "pgstat.h" #include "storage/indexfsm.h" #include "storage/predicate.h" #include "storage/procarray.h" @@ -183,13 +184,15 @@ _bt_vacuum_needs_cleanup(Relation rel) BTMetaPageData *metad; uint32 btm_version; BlockNumber prev_num_delpages; + bool hit; /* * Copy details from metapage to local variables quickly. * * Note that we deliberately avoid using cached version of metapage here. */ - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); btm_version = metad->btm_version; @@ -234,6 +237,7 @@ _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages) Buffer metabuf; Page metapg; BTMetaPageData *metad; + bool hit; /* * On-disk compatibility note: The btm_last_cleanup_num_delpages metapage @@ -253,7 +257,8 @@ _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, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); @@ -350,6 +355,7 @@ _bt_getroot(Relation rel, Relation heaprel, int access) BlockNumber rootblkno; uint32 rootlevel; BTMetaPageData *metad; + bool hit; Assert(access == BT_READ || heaprel != NULL); @@ -373,7 +379,8 @@ _bt_getroot(Relation rel, Relation heaprel, int access) Assert(rootblkno != P_NONE); rootlevel = metad->btm_fastlevel; - rootbuf = _bt_getbuf(rel, rootblkno, BT_READ); + rootbuf = _bt_getbuf(rel, rootblkno, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); rootpage = BufferGetPage(rootbuf); rootopaque = BTPageGetOpaque(rootpage); @@ -399,7 +406,8 @@ _bt_getroot(Relation rel, Relation heaprel, int access) rel->rd_amcache = NULL; } - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metad = _bt_getmeta(rel, metabuf); /* if no root page initialized yet, do it */ @@ -535,7 +543,8 @@ _bt_getroot(Relation rel, Relation heaprel, int access) for (;;) { - rootbuf = _bt_relandgetbuf(rel, rootbuf, rootblkno, BT_READ); + rootbuf = _bt_relandgetbuf(rel, rootbuf, rootblkno, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); rootpage = BufferGetPage(rootbuf); rootopaque = BTPageGetOpaque(rootpage); @@ -588,6 +597,7 @@ _bt_gettrueroot(Relation rel) BlockNumber rootblkno; uint32 rootlevel; BTMetaPageData *metad; + bool hit; /* * We don't try to use cached metapage data here, since (a) this path is @@ -599,7 +609,8 @@ _bt_gettrueroot(Relation rel) pfree(rel->rd_amcache); rel->rd_amcache = NULL; - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metapg = BufferGetPage(metabuf); metaopaque = BTPageGetOpaque(metapg); metad = BTPageGetMeta(metapg); @@ -638,7 +649,8 @@ _bt_gettrueroot(Relation rel) for (;;) { - rootbuf = _bt_relandgetbuf(rel, rootbuf, rootblkno, BT_READ); + rootbuf = _bt_relandgetbuf(rel, rootbuf, rootblkno, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); rootpage = BufferGetPage(rootbuf); rootopaque = BTPageGetOpaque(rootpage); @@ -679,8 +691,10 @@ _bt_getrootheight(Relation rel) if (rel->rd_amcache == NULL) { Buffer metabuf; + bool hit; - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metad = _bt_getmeta(rel, metabuf); /* @@ -743,8 +757,10 @@ _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage) if (rel->rd_amcache == NULL) { Buffer metabuf; + bool hit; - metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); metad = _bt_getmeta(rel, metabuf); /* @@ -842,14 +858,14 @@ _bt_checkpage(Relation rel, Buffer buf) * as _bt_lockbuf(). */ Buffer -_bt_getbuf(Relation rel, BlockNumber blkno, int access) +_bt_getbuf(Relation rel, BlockNumber blkno, int access, bool *hit) { Buffer buf; Assert(BlockNumberIsValid(blkno)); /* Read an existing block of the relation */ - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, hit); _bt_lockbuf(rel, buf, access); _bt_checkpage(rel, buf); @@ -903,7 +919,7 @@ _bt_allocbuf(Relation rel, Relation heaprel) blkno = GetFreeIndexPage(rel); if (blkno == InvalidBlockNumber) break; - buf = ReadBuffer(rel, blkno); + buf = ReadBuffer(rel, blkno, NULL); if (_bt_conditionallockbuf(rel, buf)) { page = BufferGetPage(buf); @@ -1000,14 +1016,14 @@ _bt_allocbuf(Relation rel, Relation heaprel) * is when the target page is the same one already in the buffer. */ Buffer -_bt_relandgetbuf(Relation rel, Buffer obuf, BlockNumber blkno, int access) +_bt_relandgetbuf(Relation rel, Buffer obuf, BlockNumber blkno, int access, bool *hit) { Buffer buf; Assert(BlockNumberIsValid(blkno)); if (BufferIsValid(obuf)) _bt_unlockbuf(rel, obuf); - buf = ReleaseAndReadBuffer(obuf, rel, blkno); + buf = ReleaseAndReadBuffer(obuf, rel, blkno, hit); _bt_lockbuf(rel, buf, access); _bt_checkpage(rel, buf); @@ -1703,7 +1719,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, leftsib, BT_READ, NULL); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); @@ -1758,7 +1774,7 @@ _bt_rightsib_halfdeadflag(Relation rel, BlockNumber leafrightsib) Assert(leafrightsib != P_NONE); - buf = _bt_getbuf(rel, leafrightsib, BT_READ); + buf = _bt_getbuf(rel, leafrightsib, BT_READ, NULL); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); @@ -2062,7 +2078,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate) if (!rightsib_empty) break; - leafbuf = _bt_getbuf(rel, rightsib, BT_WRITE); + leafbuf = _bt_getbuf(rel, rightsib, BT_WRITE, NULL); } } @@ -2335,6 +2351,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, uint32 targetlevel; IndexTuple leafhikey; BlockNumber leaftopparent; + bool hit; page = BufferGetPage(leafbuf); opaque = BTPageGetOpaque(page); @@ -2374,7 +2391,8 @@ _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, target, BT_READ, &hit); + pgstat_count_metadata_buffer(rel, hit); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); leftsib = opaque->btpo_prev; @@ -2401,7 +2419,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, leftsib, BT_WRITE, NULL); page = BufferGetPage(lbuf); opaque = BTPageGetOpaque(page); while (P_ISDELETED(opaque) || opaque->btpo_next != target) @@ -2449,7 +2467,8 @@ _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, leftsib, BT_WRITE, &hit); + pgstat_count_buffer(rel, !P_ISLEAF(opaque), hit); page = BufferGetPage(lbuf); opaque = BTPageGetOpaque(page); } @@ -2513,7 +2532,8 @@ _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, rightsib, BT_WRITE, &hit); + pgstat_count_buffer(rel, !P_ISLEAF(opaque), hit); page = BufferGetPage(rbuf); opaque = BTPageGetOpaque(page); @@ -2569,7 +2589,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, BTREE_METAPAGE, BT_WRITE, &hit); + pgstat_count_metadata_buffer(rel, hit); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index dc244ae24c..7aa24e1f12 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -1146,7 +1146,7 @@ backtrack: * buffer access strategy. */ buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - info->strategy); + info->strategy, NULL); _bt_lockbuf(rel, buf, BT_READ); page = BufferGetPage(buf); opaque = NULL; diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 472ce06f19..203816c418 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -126,6 +126,7 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, IndexTuple itup; BlockNumber child; BTStack new_stack; + bool hit; /* * Race -- the page we just grabbed may have split since we read its @@ -178,7 +179,8 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, page_access = BT_WRITE; /* drop the read lock on the page, then acquire one on its child */ - *bufP = _bt_relandgetbuf(rel, *bufP, child, page_access); + *bufP = _bt_relandgetbuf(rel, *bufP, child, page_access, &hit); + pgstat_count_buffer(rel, opaque->btpo_level != 1, hit); /* okay, all set to move down a level */ stack_in = new_stack; @@ -249,6 +251,7 @@ _bt_moveright(Relation rel, Page page; BTPageOpaque opaque; int32 cmpval; + bool hit; Assert(!forupdate || heaprel != NULL); @@ -299,14 +302,16 @@ _bt_moveright(Relation rel, _bt_relbuf(rel, buf); /* re-acquire the lock in the right mode, and re-check */ - buf = _bt_getbuf(rel, blkno, access); + buf = _bt_getbuf(rel, blkno, access, &hit); + pgstat_count_buffer(rel, !P_ISLEAF(opaque), hit); continue; } if (P_IGNORE(opaque) || _bt_compare(rel, key, page, P_HIKEY) >= cmpval) { /* step right one page */ - buf = _bt_relandgetbuf(rel, buf, opaque->btpo_next, access); + buf = _bt_relandgetbuf(rel, buf, opaque->btpo_next, access, &hit); + pgstat_count_buffer(rel, !P_ISLEAF(opaque), hit); continue; } else @@ -2200,6 +2205,8 @@ static bool _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, BlockNumber lastcurrblkno, ScanDirection dir, bool seized) { + bool hit; + Relation rel = scan->indexRelation; BTScanOpaque so = (BTScanOpaque) scan->opaque; @@ -2246,7 +2253,8 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, { /* read blkno, but check for interrupts first */ CHECK_FOR_INTERRUPTS(); - so->currPos.buf = _bt_getbuf(rel, blkno, BT_READ); + so->currPos.buf = _bt_getbuf(rel, blkno, BT_READ, &hit); + pgstat_count_record_buffer(rel, hit); } else { @@ -2342,10 +2350,11 @@ _bt_lock_and_validate_left(Relation rel, BlockNumber *blkno, Page page; BTPageOpaque opaque; int tries; + bool hit; /* check for interrupts while we're not holding any buffer lock */ CHECK_FOR_INTERRUPTS(); - buf = _bt_getbuf(rel, *blkno, BT_READ); + buf = _bt_getbuf(rel, *blkno, BT_READ, NULL); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); @@ -2372,7 +2381,8 @@ _bt_lock_and_validate_left(Relation rel, BlockNumber *blkno, break; /* step right */ *blkno = opaque->btpo_next; - buf = _bt_relandgetbuf(rel, buf, *blkno, BT_READ); + buf = _bt_relandgetbuf(rel, buf, *blkno, BT_READ, &hit); + pgstat_count_buffer(rel, P_ISLEAF(opaque), hit); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); } @@ -2382,7 +2392,7 @@ _bt_lock_and_validate_left(Relation rel, BlockNumber *blkno, * _bt_readpage, which is passed by caller as lastcurrblkno) to see * what's up with its prev sibling link */ - buf = _bt_relandgetbuf(rel, buf, lastcurrblkno, BT_READ); + buf = _bt_relandgetbuf(rel, buf, lastcurrblkno, BT_READ, NULL); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); if (P_ISDELETED(opaque)) @@ -2399,7 +2409,8 @@ _bt_lock_and_validate_left(Relation rel, BlockNumber *blkno, elog(ERROR, "fell off the end of index \"%s\"", RelationGetRelationName(rel)); lastcurrblkno = opaque->btpo_next; - buf = _bt_relandgetbuf(rel, buf, lastcurrblkno, BT_READ); + buf = _bt_relandgetbuf(rel, buf, lastcurrblkno, BT_READ, &hit); + pgstat_count_buffer(rel, !P_ISLEAF(opaque), hit); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); if (!P_ISDELETED(opaque)) @@ -2456,6 +2467,7 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost) OffsetNumber offnum; BlockNumber blkno; IndexTuple itup; + bool hit; /* * If we are looking for a leaf page, okay to descend from fast root; @@ -2488,7 +2500,8 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost) if (blkno == P_NONE) elog(ERROR, "fell off the end of index \"%s\"", RelationGetRelationName(rel)); - buf = _bt_relandgetbuf(rel, buf, blkno, BT_READ); + buf = _bt_relandgetbuf(rel, buf, blkno, BT_READ, &hit); + pgstat_count_record_buffer(rel, hit); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); } @@ -2511,7 +2524,8 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost) itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); blkno = BTreeTupleGetDownLink(itup); - buf = _bt_relandgetbuf(rel, buf, blkno, BT_READ); + buf = _bt_relandgetbuf(rel, buf, blkno, BT_READ, &hit); + pgstat_count_record_buffer(rel, hit); page = BufferGetPage(buf); opaque = BTPageGetOpaque(page); } diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 693e43c674..a550faa84e 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2368,8 +2368,9 @@ _bt_killitems(IndexScanDesc scan) Buffer buf; droppedpin = true; - /* Attempt to re-read the buffer, getting pin and lock. */ - buf = _bt_getbuf(scan->indexRelation, so->currPos.currPage, BT_READ); + /* Attempt to re-read the buffer, getting pin andlock. */ + buf = _bt_getbuf(scan->indexRelation, so->currPos.currPage, BT_READ, + NULL); page = BufferGetPage(buf); if (BufferGetLSNAtomic(buf) == so->currPos.lsn) diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c index af6b27b213..96ca5a91a2 100644 --- a/src/backend/access/spgist/spgdoinsert.c +++ b/src/backend/access/spgist/spgdoinsert.c @@ -2065,13 +2065,13 @@ spgdoinsert(Relation index, SpGistState *state, else if (parent.buffer == InvalidBuffer) { /* we hold no parent-page lock, so no deadlock is possible */ - current.buffer = ReadBuffer(index, current.blkno); + current.buffer = ReadBuffer(index, current.blkno, NULL); LockBuffer(current.buffer, BUFFER_LOCK_EXCLUSIVE); } else if (current.blkno != parent.blkno) { /* descend to a new child page */ - current.buffer = ReadBuffer(index, current.blkno); + current.buffer = ReadBuffer(index, current.blkno, NULL); /* * Attempt to acquire lock on child page. We must beware of diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index 53f910e9d8..85f6e91af0 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -847,13 +847,13 @@ redirect: if (buffer == InvalidBuffer) { - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); } else if (blkno != BufferGetBlockNumber(buffer)) { UnlockReleaseBuffer(buffer); - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); } diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index 367c36ef9a..ec0c455e6d 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -267,7 +267,7 @@ spgGetCache(Relation index) Buffer metabuffer; SpGistMetaPageData *metadata; - metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO, NULL); LockBuffer(metabuffer, BUFFER_LOCK_SHARE); metadata = SpGistPageGetMeta(BufferGetPage(metabuffer)); @@ -407,7 +407,7 @@ SpGistNewBuffer(Relation index) if (SpGistBlockIsFixed(blkno)) continue; - buffer = ReadBuffer(index, blkno); + buffer = ReadBuffer(index, blkno, NULL); /* * We have to guard against the possibility that someone else already @@ -452,7 +452,7 @@ SpGistUpdateMetaPage(Relation index) { Buffer metabuffer; - metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO); + metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO, NULL); if (ConditionalLockBuffer(metabuffer)) { @@ -601,7 +601,7 @@ SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew) Buffer buffer; Page page; - buffer = ReadBuffer(index, lup->blkno); + buffer = ReadBuffer(index, lup->blkno, NULL); if (!ConditionalLockBuffer(buffer)) { diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c index eeddacd0d5..b4cf3470b6 100644 --- a/src/backend/access/spgist/spgvacuum.c +++ b/src/backend/access/spgist/spgvacuum.c @@ -628,7 +628,7 @@ spgvacuumpage(spgBulkDeleteState *bds, BlockNumber blkno) vacuum_delay_point(false); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, bds->info->strategy); + RBM_NORMAL, bds->info->strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); page = (Page) BufferGetPage(buffer); @@ -709,7 +709,7 @@ spgprocesspending(spgBulkDeleteState *bds) /* examine the referenced page */ blkno = ItemPointerGetBlockNumber(&pitem->tid); buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno, - RBM_NORMAL, bds->info->strategy); + RBM_NORMAL, bds->info->strategy, NULL); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); page = (Page) BufferGetPage(buffer); diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index 14d583ae7a..8efecc6e19 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -1300,7 +1300,7 @@ log_newpage_range(Relation rel, ForkNumber forknum, while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk) { Buffer buf = ReadBufferExtended(rel, forknum, blkno, - RBM_NORMAL, NULL); + RBM_NORMAL, NULL, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index eff0990957..7567e4987f 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -758,6 +758,10 @@ CREATE VIEW pg_statio_all_tables AS pg_stat_get_blocks_hit(C.oid) AS heap_blks_hit, I.idx_blks_read AS idx_blks_read, I.idx_blks_hit AS idx_blks_hit, + I.idx_metadata_blks_read AS idx_metadata_blks_read, + I.idx_metadata_blks_hit AS idx_metadata_blks_hit, + I.idx_record_blks_read AS idx_record_blks_read, + I.idx_record_blks_hit AS idx_record_blks_hit, pg_stat_get_blocks_fetched(T.oid) - pg_stat_get_blocks_hit(T.oid) AS toast_blks_read, pg_stat_get_blocks_hit(T.oid) AS toast_blks_hit, @@ -771,7 +775,17 @@ CREATE VIEW pg_statio_all_tables AS pg_stat_get_blocks_hit(indexrelid))::bigint AS idx_blks_read, sum(pg_stat_get_blocks_hit(indexrelid))::bigint - AS idx_blks_hit + AS idx_blks_hit, + sum(pg_stat_get_metadata_blocks_fetched(indexrelid) - + pg_stat_get_metadata_blocks_hit(indexrelid))::bigint + AS idx_metadata_blks_read, + sum(pg_stat_get_metadata_blocks_hit(indexrelid))::bigint + AS idx_metadata_blks_hit, + sum(pg_stat_get_record_blocks_fetched(indexrelid) - + pg_stat_get_record_blocks_hit(indexrelid))::bigint + AS idx_record_blks_read, + sum(pg_stat_get_record_blocks_hit(indexrelid))::bigint + AS idx_record_blks_hit FROM pg_index WHERE indrelid = C.oid ) I ON true LEFT JOIN LATERAL ( SELECT sum(pg_stat_get_blocks_fetched(indexrelid) - @@ -828,7 +842,13 @@ CREATE VIEW pg_statio_all_indexes AS I.relname AS indexrelname, pg_stat_get_blocks_fetched(I.oid) - pg_stat_get_blocks_hit(I.oid) AS idx_blks_read, - pg_stat_get_blocks_hit(I.oid) AS idx_blks_hit + pg_stat_get_blocks_hit(I.oid) AS idx_blks_hit, + pg_stat_get_metadata_blocks_fetched(I.oid) - + pg_stat_get_metadata_blocks_hit(I.oid) AS idx_metadata_blks_read, + pg_stat_get_metadata_blocks_hit(I.oid) AS idx_metadata_blks_hit, + pg_stat_get_record_blocks_fetched(I.oid) - + pg_stat_get_record_blocks_hit(I.oid) AS idx_record_blks_read, + pg_stat_get_record_blocks_hit(I.oid) AS idx_record_blks_hit FROM pg_class C JOIN pg_index X ON C.oid = X.indrelid JOIN pg_class I ON I.oid = X.indexrelid @@ -1062,6 +1082,12 @@ CREATE VIEW pg_stat_database AS pg_stat_get_db_blocks_fetched(D.oid) - pg_stat_get_db_blocks_hit(D.oid) AS blks_read, pg_stat_get_db_blocks_hit(D.oid) AS blks_hit, + pg_stat_get_db_metadata_blocks_fetched(D.oid) - + pg_stat_get_db_metadata_blocks_hit(D.oid) AS metadata_blks_read, + pg_stat_get_db_metadata_blocks_hit(D.oid) AS metadata_blks_hit, + pg_stat_get_db_record_blocks_fetched(D.oid) - + pg_stat_get_db_record_blocks_hit(D.oid) AS record_blks_read, + pg_stat_get_db_record_blocks_hit(D.oid) AS record_blks_hit, pg_stat_get_db_tuples_returned(D.oid) AS tup_returned, pg_stat_get_db_tuples_fetched(D.oid) AS tup_fetched, pg_stat_get_db_tuples_inserted(D.oid) AS tup_inserted, diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 4b7c5113aa..270c9bf826 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1194,7 +1194,7 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple) sequence_magic *sm; Form_pg_sequence_data seq; - *buf = ReadBuffer(rel, 0); + *buf = ReadBuffer(rel, 0, NULL); LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE); page = BufferGetPage(*buf); diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c index 99e44ed99f..03fbc85eac 100644 --- a/src/backend/storage/aio/read_stream.c +++ b/src/backend/storage/aio/read_stream.c @@ -267,7 +267,8 @@ read_stream_start_pending_read(ReadStream *stream, bool suppress_advice) &stream->buffers[buffer_index], stream->pending_read_blocknum, &nblocks, - flags); + flags, + NULL); stream->pinned_buffers += nblocks; /* Remember whether we need to wait before returning this buffer. */ @@ -659,7 +660,8 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data) &stream->buffers[oldest_buffer_index], next_blocknum, stream->advice_enabled ? - READ_BUFFERS_ISSUE_ADVICE : 0))) + READ_BUFFERS_ISSUE_ADVICE : 0, + NULL))) { /* Fast return. */ return buffer; diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 75cfc2b6fe..6acb8089a5 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -486,7 +486,8 @@ ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref) static Buffer ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, ForkNumber forkNum, BlockNumber blockNum, - ReadBufferMode mode, BufferAccessStrategy strategy); + ReadBufferMode mode, BufferAccessStrategy strategy, + bool *hit); static BlockNumber ExtendBufferedRelCommon(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, @@ -743,9 +744,9 @@ ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockN * fork with RBM_NORMAL mode and default strategy. */ Buffer -ReadBuffer(Relation reln, BlockNumber blockNum) +ReadBuffer(Relation reln, BlockNumber blockNum, bool *hit) { - return ReadBufferExtended(reln, MAIN_FORKNUM, blockNum, RBM_NORMAL, NULL); + return ReadBufferExtended(reln, MAIN_FORKNUM, blockNum, RBM_NORMAL, NULL, hit); } /* @@ -791,7 +792,7 @@ ReadBuffer(Relation reln, BlockNumber blockNum) */ inline Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, - ReadBufferMode mode, BufferAccessStrategy strategy) + ReadBufferMode mode, BufferAccessStrategy strategy, bool *hit) { Buffer buf; @@ -810,7 +811,7 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, * miss. */ buf = ReadBuffer_common(reln, RelationGetSmgr(reln), 0, - forkNum, blockNum, mode, strategy); + forkNum, blockNum, mode, strategy, hit); return buf; } @@ -836,7 +837,7 @@ ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, return ReadBuffer_common(NULL, smgr, permanent ? RELPERSISTENCE_PERMANENT : RELPERSISTENCE_UNLOGGED, forkNum, blockNum, - mode, strategy); + mode, strategy, NULL); } /* @@ -1004,7 +1005,7 @@ ExtendBufferedRelTo(BufferManagerRelation bmr, { Assert(extended_by == 0); buffer = ReadBuffer_common(bmr.rel, bmr.smgr, bmr.relpersistence, - fork, extend_to - 1, mode, strategy); + fork, extend_to - 1, mode, strategy, NULL); } return buffer; @@ -1109,7 +1110,8 @@ PinBufferForBlock(Relation rel, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, - bool *foundPtr) + bool *foundPtr, + bool *hit) { BufferDesc *bufHdr; IOContext io_context; @@ -1160,8 +1162,11 @@ PinBufferForBlock(Relation rel, * zeroed instead), the per-relation stats always count them. */ pgstat_count_buffer_read(rel); - if (*foundPtr) + if (*foundPtr) { + if (hit) + *hit = true; pgstat_count_buffer_hit(rel); + } } if (*foundPtr) { @@ -1189,7 +1194,8 @@ static pg_attribute_always_inline Buffer ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, - BufferAccessStrategy strategy) + BufferAccessStrategy strategy, + bool *hit) { ReadBuffersOperation operation; Buffer buffer; @@ -1227,7 +1233,7 @@ ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, bool found; buffer = PinBufferForBlock(rel, smgr, persistence, - forkNum, blockNum, strategy, &found); + forkNum, blockNum, strategy, &found, hit); ZeroAndLockBuffer(buffer, mode, found); return buffer; } @@ -1244,7 +1250,8 @@ ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, if (StartReadBuffer(&operation, &buffer, blockNum, - flags)) + flags, + hit)) WaitReadBuffers(&operation); return buffer; @@ -1255,7 +1262,8 @@ StartReadBuffersImpl(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, - int flags) + int flags, + bool *hit) { int actual_nblocks = *nblocks; int io_buffers_len = 0; @@ -1274,7 +1282,8 @@ StartReadBuffersImpl(ReadBuffersOperation *operation, operation->forknum, blockNum + i, operation->strategy, - &found); + &found, + hit); if (found) { @@ -1365,9 +1374,10 @@ StartReadBuffers(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, - int flags) + int flags, + bool *hit) { - return StartReadBuffersImpl(operation, buffers, blockNum, nblocks, flags); + return StartReadBuffersImpl(operation, buffers, blockNum, nblocks, flags, hit); } /* @@ -1379,12 +1389,13 @@ bool StartReadBuffer(ReadBuffersOperation *operation, Buffer *buffer, BlockNumber blocknum, - int flags) + int flags, + bool *hit) { int nblocks = 1; bool result; - result = StartReadBuffersImpl(operation, buffer, blocknum, &nblocks, flags); + result = StartReadBuffersImpl(operation, buffer, blocknum, &nblocks, flags, hit); Assert(nblocks == 1); /* single block can't be short */ return result; @@ -2590,7 +2601,8 @@ MarkBufferDirty(Buffer buffer) Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, - BlockNumber blockNum) + BlockNumber blockNum, + bool *hit) { ForkNumber forkNum = MAIN_FORKNUM; BufferDesc *bufHdr; @@ -2619,7 +2631,7 @@ ReleaseAndReadBuffer(Buffer buffer, } } - return ReadBuffer(relation, blockNum); + return ReadBuffer(relation, blockNum, hit); } /* diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index 4773a9cc65..f9f6259ad4 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -593,7 +593,7 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend) return InvalidBuffer; } else - buf = ReadBufferExtended(rel, FSM_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); + buf = ReadBufferExtended(rel, FSM_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL, NULL); /* * Initializing the page when needed is trickier than it looks, because of diff --git a/src/backend/utils/activity/pgstat_database.c b/src/backend/utils/activity/pgstat_database.c index 05a8ccfdb7..bbfd75715d 100644 --- a/src/backend/utils/activity/pgstat_database.c +++ b/src/backend/utils/activity/pgstat_database.c @@ -407,6 +407,10 @@ pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait) PGSTAT_ACCUM_DBCOUNT(xact_rollback); PGSTAT_ACCUM_DBCOUNT(blocks_fetched); PGSTAT_ACCUM_DBCOUNT(blocks_hit); + PGSTAT_ACCUM_DBCOUNT(metadata_blocks_fetched); + PGSTAT_ACCUM_DBCOUNT(metadata_blocks_hit); + PGSTAT_ACCUM_DBCOUNT(record_blocks_fetched); + PGSTAT_ACCUM_DBCOUNT(record_blocks_hit); PGSTAT_ACCUM_DBCOUNT(tuples_returned); PGSTAT_ACCUM_DBCOUNT(tuples_fetched); diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c index d64595a165..c879c3b2a6 100644 --- a/src/backend/utils/activity/pgstat_relation.c +++ b/src/backend/utils/activity/pgstat_relation.c @@ -871,6 +871,10 @@ pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait) tabentry->ins_since_vacuum += lstats->counts.tuples_inserted; tabentry->blocks_fetched += lstats->counts.blocks_fetched; tabentry->blocks_hit += lstats->counts.blocks_hit; + tabentry->metadata_blocks_fetched += lstats->counts.metadata_blocks_fetched; + tabentry->metadata_blocks_hit += lstats->counts.metadata_blocks_hit; + tabentry->record_blocks_fetched += lstats->counts.record_blocks_fetched; + tabentry->record_blocks_hit += lstats->counts.record_blocks_hit; /* Clamp live_tuples in case of negative delta_live_tuples */ tabentry->live_tuples = Max(tabentry->live_tuples, 0); @@ -888,6 +892,10 @@ pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait) dbentry->tuples_deleted += lstats->counts.tuples_deleted; dbentry->blocks_fetched += lstats->counts.blocks_fetched; dbentry->blocks_hit += lstats->counts.blocks_hit; + dbentry->metadata_blocks_fetched += lstats->counts.metadata_blocks_fetched; + dbentry->metadata_blocks_hit += lstats->counts.metadata_blocks_hit; + dbentry->record_blocks_fetched += lstats->counts.record_blocks_fetched; + dbentry->record_blocks_hit += lstats->counts.record_blocks_hit; return true; } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index e9096a8849..565a96773d 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -67,6 +67,18 @@ PG_STAT_GET_RELENTRY_INT64(blocks_fetched) /* pg_stat_get_blocks_hit */ PG_STAT_GET_RELENTRY_INT64(blocks_hit) +/* pg_stat_get_metadata_blocks_fetched */ +PG_STAT_GET_RELENTRY_INT64(metadata_blocks_fetched) + +/* pg_stat_get_metadata_blocks_hit */ +PG_STAT_GET_RELENTRY_INT64(metadata_blocks_hit) + +/* pg_stat_get_record_blocks_fetched */ +PG_STAT_GET_RELENTRY_INT64(record_blocks_fetched) + +/* pg_stat_get_record_blocks_hit */ +PG_STAT_GET_RELENTRY_INT64(record_blocks_hit) + /* pg_stat_get_dead_tuples */ PG_STAT_GET_RELENTRY_INT64(dead_tuples) @@ -1031,6 +1043,18 @@ PG_STAT_GET_DBENTRY_INT64(blocks_fetched) /* pg_stat_get_db_blocks_hit */ PG_STAT_GET_DBENTRY_INT64(blocks_hit) +/* pg_stat_get_db_metadata_blocks_fetched */ +PG_STAT_GET_DBENTRY_INT64(metadata_blocks_fetched) + +/* pg_stat_get_db_metadata_blocks_hit */ +PG_STAT_GET_DBENTRY_INT64(metadata_blocks_hit) + +/* pg_stat_get_db_record_blocks_fetched */ +PG_STAT_GET_DBENTRY_INT64(record_blocks_fetched) + +/* pg_stat_get_db_record_blocks_hit */ +PG_STAT_GET_DBENTRY_INT64(record_blocks_hit) + /* pg_stat_get_db_conflict_bufferpin */ PG_STAT_GET_DBENTRY_INT64(conflict_bufferpin) diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 000c7289b8..9d7e2a6e45 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1247,10 +1247,10 @@ extern int _bt_getrootheight(Relation rel); extern void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage); extern void _bt_checkpage(Relation rel, Buffer buf); -extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access); +extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access, bool *hit); extern Buffer _bt_allocbuf(Relation rel, Relation heaprel); extern Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, - BlockNumber blkno, int access); + BlockNumber blkno, int access, bool *hit); extern void _bt_relbuf(Relation rel, Buffer buf); extern void _bt_lockbuf(Relation rel, Buffer buf, int access); extern void _bt_unlockbuf(Relation rel, Buffer buf); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 9e803d610d..5902827510 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5517,6 +5517,22 @@ proname => 'pg_stat_get_blocks_hit', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_stat_get_blocks_hit' }, + { oid => '8888', descr => 'statistics: number of record blocks fetched', + proname => 'pg_stat_get_record_blocks_fetched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_record_blocks_fetched' }, +{ oid => '8889', descr => 'statistics: number of record blocks found in cache', + proname => 'pg_stat_get_record_blocks_hit', provolatile => 's', proparallel => 'r', + prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_record_blocks_hit' }, +{ oid => '8890', descr => 'statistics: number of metadata blocks fetched', + proname => 'pg_stat_get_metadata_blocks_fetched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_metadata_blocks_fetched' }, +{ oid => '8891', descr => 'statistics: number of metadata blocks found in cache', + proname => 'pg_stat_get_metadata_blocks_hit', provolatile => 's', proparallel => 'r', + prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_metadata_blocks_hit' }, { oid => '2781', descr => 'statistics: last manual vacuum time for a table', proname => 'pg_stat_get_last_vacuum_time', provolatile => 's', proparallel => 'r', prorettype => 'timestamptz', proargtypes => 'oid', @@ -5717,6 +5733,22 @@ proname => 'pg_stat_get_db_blocks_hit', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_stat_get_db_blocks_hit' }, +{ oid => '8892', descr => 'statistics: number of db record blocks fetched', + proname => 'pg_stat_get_db_record_blocks_fetched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_record_blocks_fetched' }, +{ oid => '8893', descr => 'statistics: blocks found in cache for database', + proname => 'pg_stat_get_db_record_blocks_hit', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_record_blocks_hit' }, +{ oid => '8894', descr => 'statistics: number of metadata blocks fetched', + proname => 'pg_stat_get_db_metadata_blocks_fetched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_metadata_blocks_fetched' }, +{ oid => '8895', descr => 'statistics: number of metadata blocks found in cache', + proname => 'pg_stat_get_db_metadata_blocks_hit', provolatile => 's', proparallel => 'r', + prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_metadata_blocks_hit' }, { oid => '2758', descr => 'statistics: tuples returned for database', proname => 'pg_stat_get_db_tuples_returned', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 53f2a8458e..b846ef7529 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -154,6 +154,11 @@ typedef struct PgStat_TableCounts PgStat_Counter blocks_fetched; PgStat_Counter blocks_hit; + + PgStat_Counter metadata_blocks_fetched; + PgStat_Counter metadata_blocks_hit; + PgStat_Counter record_blocks_fetched; + PgStat_Counter record_blocks_hit; } PgStat_TableCounts; /* ---------- @@ -364,6 +369,10 @@ typedef struct PgStat_StatDBEntry PgStat_Counter xact_rollback; PgStat_Counter blocks_fetched; PgStat_Counter blocks_hit; + PgStat_Counter metadata_blocks_fetched; + PgStat_Counter metadata_blocks_hit; + PgStat_Counter record_blocks_fetched; + PgStat_Counter record_blocks_hit; PgStat_Counter tuples_returned; PgStat_Counter tuples_fetched; PgStat_Counter tuples_inserted; @@ -459,6 +468,11 @@ typedef struct PgStat_StatTabEntry PgStat_Counter blocks_fetched; PgStat_Counter blocks_hit; + PgStat_Counter metadata_blocks_fetched; + PgStat_Counter metadata_blocks_hit; + PgStat_Counter record_blocks_fetched; + PgStat_Counter record_blocks_hit; + TimestampTz last_vacuum_time; /* user initiated vacuum */ PgStat_Counter vacuum_count; TimestampTz last_autovacuum_time; /* autovacuum initiated */ @@ -707,6 +721,37 @@ extern void pgstat_report_analyze(Relation rel, if (pgstat_should_count_relation(rel)) \ (rel)->pgstat_info->counts.blocks_hit++; \ } while (0) +#define pgstat_count_metadata_buffer(rel, hit) \ + do { \ + if (pgstat_should_count_relation(rel)) { \ + (rel)->pgstat_info->counts.metadata_blocks_fetched++; \ + if ((hit)) \ + (rel)->pgstat_info->counts.metadata_blocks_hit++; \ + } \ + } while (0) +#define pgstat_count_record_buffer(rel, hit) \ + do { \ + if (pgstat_should_count_relation(rel)) { \ + (rel)->pgstat_info->counts.record_blocks_fetched++; \ + if ((hit)) \ + (rel)->pgstat_info->counts.record_blocks_hit++; \ + } \ + } while (0) +#define pgstat_count_buffer(rel, metadata, hit) \ + do { \ + if (pgstat_should_count_relation(rel)) { \ + if ((metadata)) { \ + (rel)->pgstat_info->counts.metadata_blocks_fetched++;\ + if ((hit)) \ + (rel)->pgstat_info->counts.metadata_blocks_hit++;\ + } \ + else { \ + (rel)->pgstat_info->counts.record_blocks_fetched++; \ + if ((hit)) \ + (rel)->pgstat_info->counts.record_blocks_hit++; \ + } \ + } \ + } while (0) extern void pgstat_count_heap_insert(Relation rel, PgStat_Counter n); extern void pgstat_count_heap_update(Relation rel, bool hot, bool newpage); diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 7c1e4316dd..8f287f0841 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -201,10 +201,10 @@ extern PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum); extern bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, Buffer recent_buffer); -extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); +extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum, bool *hit); extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, - BufferAccessStrategy strategy); + BufferAccessStrategy strategy, bool *hit); extern Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, @@ -213,12 +213,14 @@ extern Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, extern bool StartReadBuffer(ReadBuffersOperation *operation, Buffer *buffer, BlockNumber blocknum, - int flags); + int flags, + bool *hit); extern bool StartReadBuffers(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, - int flags); + int flags, + bool *hit); extern void WaitReadBuffers(ReadBuffersOperation *operation); extern void ReleaseBuffer(Buffer buffer); @@ -229,7 +231,7 @@ extern void MarkBufferDirty(Buffer buffer); extern void IncrBufferRefCount(Buffer buffer); extern void CheckBufferIsPinnedOnce(Buffer buffer); extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, - BlockNumber blockNum); + BlockNumber blockNum, bool *hit); extern Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 5baba8d39f..5217cc74a9 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1847,6 +1847,10 @@ pg_stat_database| SELECT oid AS datid, pg_stat_get_db_xact_rollback(oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(oid) - pg_stat_get_db_blocks_hit(oid)) AS blks_read, pg_stat_get_db_blocks_hit(oid) AS blks_hit, + (pg_stat_get_db_metadata_blocks_fetched(oid) - pg_stat_get_db_metadata_blocks_hit(oid)) AS metadata_blks_read, + pg_stat_get_db_metadata_blocks_hit(oid) AS metadata_blks_hit, + (pg_stat_get_db_record_blocks_fetched(oid) - pg_stat_get_db_record_blocks_hit(oid)) AS record_blks_read, + pg_stat_get_db_record_blocks_hit(oid) AS record_blks_hit, pg_stat_get_db_tuples_returned(oid) AS tup_returned, pg_stat_get_db_tuples_fetched(oid) AS tup_fetched, pg_stat_get_db_tuples_inserted(oid) AS tup_inserted, @@ -2342,7 +2346,11 @@ pg_statio_all_indexes| SELECT c.oid AS relid, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, - pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit + pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit, + (pg_stat_get_metadata_blocks_fetched(i.oid) - pg_stat_get_metadata_blocks_hit(i.oid)) AS idx_metadata_blks_read, + pg_stat_get_metadata_blocks_hit(i.oid) AS idx_metadata_blks_hit, + (pg_stat_get_record_blocks_fetched(i.oid) - pg_stat_get_record_blocks_hit(i.oid)) AS idx_record_blks_read, + pg_stat_get_record_blocks_hit(i.oid) AS idx_record_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) @@ -2363,6 +2371,10 @@ pg_statio_all_tables| SELECT c.oid AS relid, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, i.idx_blks_read, i.idx_blks_hit, + i.idx_metadata_blks_read, + i.idx_metadata_blks_hit, + i.idx_record_blks_read, + i.idx_record_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, x.idx_blks_read AS tidx_blks_read, @@ -2371,7 +2383,11 @@ pg_statio_all_tables| SELECT c.oid AS relid, LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN LATERAL ( SELECT (sum((pg_stat_get_blocks_fetched(pg_index.indexrelid) - pg_stat_get_blocks_hit(pg_index.indexrelid))))::bigint AS idx_blks_read, - (sum(pg_stat_get_blocks_hit(pg_index.indexrelid)))::bigint AS idx_blks_hit + (sum(pg_stat_get_blocks_hit(pg_index.indexrelid)))::bigint AS idx_blks_hit, + (sum((pg_stat_get_metadata_blocks_fetched(pg_index.indexrelid) - pg_stat_get_metadata_blocks_hit(pg_index.indexrelid))))::bigint AS idx_metadata_blks_read, + (sum(pg_stat_get_metadata_blocks_hit(pg_index.indexrelid)))::bigint AS idx_metadata_blks_hit, + (sum((pg_stat_get_record_blocks_fetched(pg_index.indexrelid) - pg_stat_get_record_blocks_hit(pg_index.indexrelid))))::bigint AS idx_record_blks_read, + (sum(pg_stat_get_record_blocks_hit(pg_index.indexrelid)))::bigint AS idx_record_blks_hit FROM pg_index WHERE (pg_index.indrelid = c.oid)) i ON (true)) LEFT JOIN LATERAL ( SELECT (sum((pg_stat_get_blocks_fetched(pg_index.indexrelid) - pg_stat_get_blocks_hit(pg_index.indexrelid))))::bigint AS idx_blks_read, @@ -2385,7 +2401,11 @@ pg_statio_sys_indexes| SELECT relid, relname, indexrelname, idx_blks_read, - idx_blks_hit + idx_blks_hit, + idx_metadata_blks_read, + idx_metadata_blks_hit, + idx_record_blks_read, + idx_record_blks_hit FROM pg_statio_all_indexes WHERE ((schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (schemaname ~ '^pg_toast'::text)); pg_statio_sys_sequences| SELECT relid, @@ -2402,6 +2422,10 @@ pg_statio_sys_tables| SELECT relid, heap_blks_hit, idx_blks_read, idx_blks_hit, + idx_metadata_blks_read, + idx_metadata_blks_hit, + idx_record_blks_read, + idx_record_blks_hit, toast_blks_read, toast_blks_hit, tidx_blks_read, @@ -2414,7 +2438,11 @@ pg_statio_user_indexes| SELECT relid, relname, indexrelname, idx_blks_read, - idx_blks_hit + idx_blks_hit, + idx_metadata_blks_read, + idx_metadata_blks_hit, + idx_record_blks_read, + idx_record_blks_hit FROM pg_statio_all_indexes WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text)); pg_statio_user_sequences| SELECT relid, @@ -2431,6 +2459,10 @@ pg_statio_user_tables| SELECT relid, heap_blks_hit, idx_blks_read, idx_blks_hit, + idx_metadata_blks_read, + idx_metadata_blks_hit, + idx_record_blks_read, + idx_record_blks_hit, toast_blks_read, toast_blks_hit, tidx_blks_read, -- 2.39.5 (Apple Git-154)