Skip to content

Commit 2e46bf6

Browse files
committed
pgstattuple: Use a BufferAccessStrategy object to avoid cache-trashing.
Jaime Casanova, reviewed by Noah Misch, slightly modified by me.
1 parent 97c8509 commit 2e46bf6

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

contrib/pgstattuple/pgstatindex.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pgstatindex(PG_FUNCTION_ARGS)
9595
BlockNumber nblocks;
9696
BlockNumber blkno;
9797
BTIndexStat indexStat;
98+
BufferAccessStrategy bstrategy = GetAccessStrategy(BAS_BULKREAD);
9899

99100
if (!superuser())
100101
ereport(ERROR,
@@ -122,7 +123,7 @@ pgstatindex(PG_FUNCTION_ARGS)
122123
* Read metapage
123124
*/
124125
{
125-
Buffer buffer = ReadBuffer(rel, 0);
126+
Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy);
126127
Page page = BufferGetPage(buffer);
127128
BTMetaPageData *metad = BTPageGetMeta(page);
128129

@@ -159,7 +160,7 @@ pgstatindex(PG_FUNCTION_ARGS)
159160
CHECK_FOR_INTERRUPTS();
160161

161162
/* Read and lock buffer */
162-
buffer = ReadBuffer(rel, blkno);
163+
buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
163164
LockBuffer(buffer, BUFFER_LOCK_SHARE);
164165

165166
page = BufferGetPage(buffer);

contrib/pgstattuple/pgstattuple.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,22 @@ typedef struct pgstattuple_type
6161
uint64 free_space; /* free/reusable space in bytes */
6262
} pgstattuple_type;
6363

64-
typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber);
64+
typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber,
65+
BufferAccessStrategy);
6566

6667
static Datum build_pgstattuple_type(pgstattuple_type *stat,
6768
FunctionCallInfo fcinfo);
6869
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo);
6970
static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo);
7071
static void pgstat_btree_page(pgstattuple_type *stat,
71-
Relation rel, BlockNumber blkno);
72+
Relation rel, BlockNumber blkno,
73+
BufferAccessStrategy bstrategy);
7274
static void pgstat_hash_page(pgstattuple_type *stat,
73-
Relation rel, BlockNumber blkno);
75+
Relation rel, BlockNumber blkno,
76+
BufferAccessStrategy bstrategy);
7477
static void pgstat_gist_page(pgstattuple_type *stat,
75-
Relation rel, BlockNumber blkno);
78+
Relation rel, BlockNumber blkno,
79+
BufferAccessStrategy bstrategy);
7680
static Datum pgstat_index(Relation rel, BlockNumber start,
7781
pgstat_page pagefn, FunctionCallInfo fcinfo);
7882
static void pgstat_index_page(pgstattuple_type *stat, Page page,
@@ -273,12 +277,17 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
273277
BlockNumber tupblock;
274278
Buffer buffer;
275279
pgstattuple_type stat = {0};
280+
BufferAccessStrategy bstrategy;
276281

277282
/* Disable syncscan because we assume we scan from block zero upwards */
278283
scan = heap_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false);
279284

280285
nblocks = scan->rs_nblocks; /* # blocks to be scanned */
281286

287+
/* prepare access strategy for this table */
288+
bstrategy = GetAccessStrategy(BAS_BULKREAD);
289+
scan->rs_strategy = bstrategy;
290+
282291
/* scan the relation */
283292
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
284293
{
@@ -312,7 +321,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
312321
{
313322
CHECK_FOR_INTERRUPTS();
314323

315-
buffer = ReadBuffer(rel, block);
324+
buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, RBM_NORMAL, bstrategy);
316325
LockBuffer(buffer, BUFFER_LOCK_SHARE);
317326
stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer));
318327
UnlockReleaseBuffer(buffer);
@@ -325,7 +334,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
325334
{
326335
CHECK_FOR_INTERRUPTS();
327336

328-
buffer = ReadBuffer(rel, block);
337+
buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, RBM_NORMAL, bstrategy);
329338
LockBuffer(buffer, BUFFER_LOCK_SHARE);
330339
stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer));
331340
UnlockReleaseBuffer(buffer);
@@ -343,12 +352,13 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
343352
* pgstat_btree_page -- check tuples in a btree page
344353
*/
345354
static void
346-
pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
355+
pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
356+
BufferAccessStrategy bstrategy)
347357
{
348358
Buffer buf;
349359
Page page;
350360

351-
buf = ReadBuffer(rel, blkno);
361+
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
352362
LockBuffer(buf, BT_READ);
353363
page = BufferGetPage(buf);
354364

@@ -386,13 +396,14 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
386396
* pgstat_hash_page -- check tuples in a hash page
387397
*/
388398
static void
389-
pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
399+
pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
400+
BufferAccessStrategy bstrategy)
390401
{
391402
Buffer buf;
392403
Page page;
393404

394405
_hash_getlock(rel, blkno, HASH_SHARE);
395-
buf = _hash_getbuf(rel, blkno, HASH_READ, 0);
406+
buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy);
396407
page = BufferGetPage(buf);
397408

398409
if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
@@ -429,12 +440,13 @@ pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
429440
* pgstat_gist_page -- check tuples in a gist page
430441
*/
431442
static void
432-
pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno)
443+
pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
444+
BufferAccessStrategy bstrategy)
433445
{
434446
Buffer buf;
435447
Page page;
436448

437-
buf = ReadBuffer(rel, blkno);
449+
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
438450
LockBuffer(buf, GIST_SHARE);
439451
gistcheckpage(rel, buf);
440452
page = BufferGetPage(buf);
@@ -461,8 +473,12 @@ pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn,
461473
{
462474
BlockNumber nblocks;
463475
BlockNumber blkno;
476+
BufferAccessStrategy bstrategy;
464477
pgstattuple_type stat = {0};
465478

479+
/* prepare access strategy for this index */
480+
bstrategy = GetAccessStrategy(BAS_BULKREAD);
481+
466482
blkno = start;
467483
for (;;)
468484
{
@@ -483,7 +499,7 @@ pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn,
483499
{
484500
CHECK_FOR_INTERRUPTS();
485501

486-
pagefn(&stat, rel, blkno);
502+
pagefn(&stat, rel, blkno, bstrategy);
487503
}
488504
}
489505

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy