DBサイズをグラフ化するmuninプラグインを作成しようとしています。 _pg_database_size
_を使用すると同時に、そのコンポーネントもグラフ化したいと思います。
これまでのところ、私は次のことを考え出しました:
_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
_
ただし、これらの5つの値を合計すると、_pg_database_size
_の結果と同じnotが返されます。大きなDBの場合、違いはそれほど重要ではないようです。
より大きな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)
_
より小さい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)
_
何が欠けていますか?
おそらく関連しているかもしれませんが、そうではないかもしれません。彼らは巨大です。私のクエリの何かが間違っていますか?
以下は、さまざまな値を検査するために使用したスクリプトです。
_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;
_
pg_database_size()
は基本的に、$PGDATA/base/oid-of-database
(データベースごとのデータディレクトリ)のサイズに加えて、CREATE TABLESPACE
で追加されたデフォルト以外のテーブルスペース内のそのようなすべてのディレクトリのサイズをファイルシステムに照会します。
これらのディレクトリに関係に関係のないファイルがある場合、それらもカウントされます。ランダムなデータベースを見ると、その場合のpg_internal.init
、PG_VERSION
、pg_filenode.map
がわかります。これらは合計してディレクトリサイズになり、制御クエリではカウントされません。
浮遊データファイルが存在する可能性もあります。具体的な例については、 部分的に構築され、停電によって終了したインデックスによって使用されたスペースを再利用する方法 を参照してください。また、pg_class
に対してクエリを実行しても、定義から見つけることはできず、ディスク上のデータベースサイズでカウントされます。
クエリに関しては、オブジェクトサイズの合計を取得する目的でのみ、より単純なバージョンをお勧めします。
select sum(pg_total_relation_size(oid))
from pg_class
where relkind in ('r','m','S')
and not relisshared
共有関係はこのクエリから削除されることに注意してください(not relisshared
)。共有オブジェクトはすべてのデータベースから見ることができ、どのデータベースのディレクトリにも属していません。それらは$PGDATA/global
にあります。サイズが大きくなると予想される共有テーブルの1つは pg_shdepend
です。元のクエリでこれを見落とすと、過大評価になります(トーストテーブルに関する@jjanesコメントに加えて)。
トーストテーブルを2回カウントしています。いったん所有者の下にpg_total_relation_size(reltoastrelid)
として、再びpg_classの自分のエントリの下に。必要なものをフィルタリングするには、reltypeではなくrelkindを使用する必要があります。
また、RDBMSをこの範囲までマイクロ管理しようとしても、ほとんど効果がありません。