Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)