Skip to content

Commit 1c72614

Browse files
authored
Merge pull request #85 from NikolayS/feat/buffercache-report
feat(b6): add buffer cache contents report
2 parents 4a128c1 + 55429a7 commit 1c72614

4 files changed

Lines changed: 58 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ jobs:
5454
psql -h localhost -U postgres -d test -c 'CREATE EXTENSION IF NOT EXISTS pg_stat_statements;' || echo "Warning: pg_stat_statements not available"
5555
psql -h localhost -U postgres -d test -c 'CREATE EXTENSION IF NOT EXISTS pgstattuple;'
5656
psql -h localhost -U postgres -d test -c 'CREATE EXTENSION IF NOT EXISTS intarray;'
57+
psql -h localhost -U postgres -d test -c 'CREATE EXTENSION IF NOT EXISTS pg_buffercache;'
5758
5859
# Minimal privilege user
5960
psql -h localhost -U postgres -d test -c "CREATE USER dba_user;"

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Then connect to any Postgres server via psql and type `:dba` to open the interac
4242
| b3 | Table bloat via `pgstattuple` (expensive) |
4343
| b4 | B-tree index bloat via `pgstattuple` (expensive) |
4444
| b5 | Tables and columns without stats (bloat cannot be estimated) |
45+
| b6 | Buffer cache contents (requires `pg_buffercache`, expensive) |
4546

4647
### Indexes
4748
| ID | Report |
@@ -69,6 +70,7 @@ Then connect to any Postgres server via psql and type `:dba` to open the interac
6970
| ID | Report |
7071
|----|--------|
7172
| t1 | Postgres parameters tuning |
73+
| t2 | Objects with custom storage parameters |
7274
| e1 | Installed extensions |
7375
| p1 | Alignment padding analysis (experimental) |
7476
| r1 | Create user with random password (interactive) |

sql/b6_buffercache.sql

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
-- Buffer cache contents (requires pg_buffercache; expensive on large shared_buffers)
2+
3+
with buf as (
4+
select
5+
c.oid as relid,
6+
n.nspname as schema_name,
7+
c.relname,
8+
case c.relkind
9+
when 'r' then 'table'
10+
when 'i' then 'index'
11+
when 't' then 'TOAST table'
12+
when 'm' then 'materialized view'
13+
when 'S' then 'sequence'
14+
else c.relkind::text
15+
end as object_type,
16+
count(*) as buffers,
17+
count(*) filter (where b.isdirty) as dirty_buffers,
18+
round(
19+
100.0 * count(*) / (
20+
select count(*) from pg_buffercache where relfilenode is not null
21+
),
22+
1
23+
) as pct_of_cache,
24+
round(
25+
100.0 * count(*) / greatest(pg_relation_size(c.oid) / current_setting('block_size')::int, 1),
26+
1
27+
) as pct_of_rel,
28+
pg_size_pretty(count(*) * current_setting('block_size')::int) as cached_size,
29+
pg_size_pretty(pg_relation_size(c.oid)) as rel_size
30+
from pg_buffercache as b
31+
join pg_class as c on b.relfilenode = pg_relation_filenode(c.oid)
32+
join pg_namespace as n on c.relnamespace = n.oid
33+
where b.relfilenode is not null
34+
and n.nspname not in ('pg_catalog', 'information_schema')
35+
and n.nspname !~ '^pg_toast'
36+
group by c.oid, n.nspname, c.relname, c.relkind
37+
)
38+
select
39+
coalesce(nullif(schema_name, 'public') || '.', '') || relname as "Object",
40+
object_type as "Type",
41+
rel_size as "Size",
42+
cached_size as "Cached",
43+
pct_of_rel || '%' as "% of Rel",
44+
pct_of_cache || '%' as "% of Cache",
45+
buffers as "Buffers",
46+
dirty_buffers as "Dirty"
47+
from buf
48+
order by buffers desc
49+
limit 50;

start.psql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
\echo ' b3 – Table bloat (requires pgstattuple; expensive)'
1111
\echo ' b4 – B-tree indexes bloat (requires pgstattuple; expensive)'
1212
\echo ' b5 – Tables and columns without stats (so bloat cannot be estimated)'
13+
\echo ' b6 – Buffer cache contents (requires pg_buffercache; expensive)'
1314
\echo ' c1 – Index (re)creation progress (CREATE INDEX / REINDEX)'
1415
\echo ' e1 – Extensions installed in current database'
1516
\echo ' i1 – Unused and rarely used indexes'
@@ -44,6 +45,7 @@ select
4445
:d_stp::text = 'b3' as d_step_is_b3,
4546
:d_stp::text = 'b4' as d_step_is_b4,
4647
:d_stp::text = 'b5' as d_step_is_b5,
48+
:d_stp::text = 'b6' as d_step_is_b6,
4749
:d_stp::text = 'c1' as d_step_is_c1,
4850
:d_stp::text = 'e1' as d_step_is_e1,
4951
:d_stp::text = 'i1' as d_step_is_i1,
@@ -106,6 +108,10 @@ select
106108
\ir ./sql/b5_tables_no_stats.sql
107109
\prompt 'Press <Enter> to continue…' d_dummy
108110
\ir ./start.psql
111+
\elif :d_step_is_b6
112+
\ir ./sql/b6_buffercache.sql
113+
\prompt 'Press <Enter> to continue…' d_dummy
114+
\ir ./start.psql
109115
\elif :d_step_is_c1
110116
\ir ./sql/c1_index_create_progress.sql
111117
\prompt 'Press <Enter> to continue…' d_dummy

0 commit comments

Comments
 (0)