I’m trying to write a munin plugin to graph DB sizes. Alongside using pg_database_size
I want to graph the components thereof as well.
So far, I’ve come up with the following:
SELECT
SUM(pg_relation_size(oid, 'main')) AS main_size,
SUM(pg_relation_size(oid, 'vm')) AS vm_size,
SUM(pg_relation_size(oid, 'fsm')) AS fsm_size,
SUM(
CASE reltoastrelid
WHEN 0 THEN 0
ELSE pg_total_relation_size(reltoastrelid)
END
) AS toast_size,
SUM(pg_indexes_size(oid)) AS indexes_size
FROM pg_class
WHERE reltype != 0 -- 0=indices, covered by pg_indexes_size
However, summing up those 5 values returns me something which is not the same as the result of pg_database_size
. The difference seems to be less significant for larger DBs.
Example on a larger DB:
┌──────────┬────────┬─────────┬─────────┬──────────┬───────────────┬──────────────────┬─────────┐
│ main │ vm │ fsm │ toast │ indexes │ sum_of_values │ pg_database_size │ diff │
├──────────┼────────┼─────────┼─────────┼──────────┼───────────────┼──────────────────┼─────────┤
│ 72441856 │ 753664 │ 2392064 │ 4677632 │ 41377792 │ 116 MB │ 111 MB │ 5222 kB │
└──────────┴────────┴─────────┴─────────┴──────────┴───────────────┴──────────────────┴─────────┘
(1 row)
Example on a smaller DB:
┌─────────┬────────┬─────────┬────────┬─────────┬───────────────┬──────────────────┬─────────┐
│ main │ vm │ fsm │ toast │ indexes │ sum_of_values │ pg_database_size │ diff │
├─────────┼────────┼─────────┼────────┼─────────┼───────────────┼──────────────────┼─────────┤
│ 2809856 │ 385024 │ 1351680 │ 557056 │ 2924544 │ 7840 kB │ 6642 kB │ 1198 kB │
└─────────┴────────┴─────────┴────────┴─────────┴───────────────┴──────────────────┴─────────┘
(1 row)
What am I missing?
Maybe related, maybe not: I’m shocked to see the index size. They are HUGE. Is something in my query wrong?
Here is a script I used to inspect the different values:
SELECT
SUM(pg_relation_size(oid, 'main')) AS main,
SUM(pg_relation_size(oid, 'vm')) AS vm,
SUM(pg_relation_size(oid, 'fsm')) AS fsm,
SUM(
CASE reltoastrelid
WHEN 0 THEN 0
ELSE pg_total_relation_size(reltoastrelid)
END
) AS toast,
SUM(pg_indexes_size(oid)) AS indexes,
pg_size_pretty(
SUM(pg_relation_size(oid, 'main'))::bigint +
SUM(pg_relation_size(oid, 'vm'))::bigint +
SUM(pg_relation_size(oid, 'fsm'))::bigint +
SUM(pg_indexes_size(oid))::bigint +
SUM(
CASE reltoastrelid
WHEN 0 THEN 0
ELSE pg_total_relation_size(reltoastrelid)
END
)::bigint
) AS sum_of_values,
pg_size_pretty(pg_database_size(current_database())) AS pg_database_size,
pg_size_pretty(
SUM(pg_relation_size(oid, 'main'))::bigint +
SUM(pg_relation_size(oid, 'vm'))::bigint +
SUM(pg_relation_size(oid, 'fsm'))::bigint +
SUM(pg_indexes_size(oid))::bigint +
SUM(
CASE reltoastrelid
WHEN 0 THEN 0
ELSE pg_total_relation_size(reltoastrelid)
END
)::bigint - pg_database_size(current_database())::bigint
) AS diff
FROM pg_class
WHERE reltype != 0;