【豆知識】pg_statsinfoのサイジング
PostgreSQLインサイド

PostgreSQLの周辺ツールの1つであるpg_statsinfoは、サーバーの統計情報(以降、スナップショットと定義)を収集・蓄積・表示することで、PostgreSQLにおける日々の処理傾向についての把握、性能劣化などの兆候や問題発生の原因把握に役立ちます。ただし、大規模な業務システムにおいて取得したスナップショットを長期間に亘って蓄積し続けると、スナップショットの保存先となるデータベース(以降、リポジトリーDBと定義)の容量を圧迫します。そこで、運用を開始する前に業務要件からスナップショットのサイズを見積もり、運用開始後は不要になったスナップショットを定期的に削除することで、システムの資源を有効活用できます。
ここでは、pg_statsinfoで取得するスナップショットのサイズ、見積もり式、運用中のサイズについての確認方法を順に解説します。今回は、pg_statsinfo 12.1をベースに説明します。

参考

  • pg_statsinfoの仕様については、オープンソース・ソフトウェアに同梱されているマニュアルを参照してください。
  • pg_statsinfoの使い方については「pg_statsinfoで統計情報を収集・蓄積する」で詳しく解説しています。

スナップショットのサイズ

スナップショットは、各インスタンスのデータベースクラスタ単位に取得されます。pg_statsinfoで取得するスナップショットのサイズには、固定値と可変値があります。固定値は、initdbコマンドでデータベースクラスタを作成した時に生成されるデータを保存するディレクトリーやpostgresデータベースなどのサイズです。可変値は、データベースクラスタ内に作成したデータベースやテーブルなどのオブジェクト数に応じたサイズです。
監視対象インスタンスが複数ある場合はその数だけスナップショット容量が必要になります。特にストリーミングレプリケーション機能を利用する場合、プライマリーサーバーとスタンバイサーバーの両方のスナップショットを1つのリポジトリーDBに格納することになり、レプリケーションを構成するインスタンス(サーバー)の数だけ必要な容量が増えるので注意してください。
以下の表に、スナップショット取得1回あたりのサイズを示します。

表1. スナップショット取得1回あたりのサイズ

分類 構成要素 基本サイズ(バイト)(注1 オブジェクト数(注2 必要なサイズ(バイト)(注3 補足
固定値 snapshot 80 1 80 スナップショット情報を格納
cpu 96 1 96 OSリソース(CPU)に関する情報を格納
device 144 1 144 OSリソース(ディスクI/O)に関する情報を格納
loadavg 48 1 48 ロードアベレージに関する情報を格納
memory 64 1 64 メモリーに関する情報を格納
bgwriter 64 1 64 バックグラウンドライタに関する情報を格納
xlog 96 1 96 WALに関する情報を格納
archive 64 1 64 WALアーカイブに関する情報を格納
database 256 1 256 データベースに関する情報を格納
tablespace 208 2 416 データベーススペースに関する情報を格納
schema 96 5 480 スキーマに関する情報を格納
table 336 40 13,440 テーブルに関する情報を格納
index 240 30 7,200 インデックスに関する情報を格納
column 160 459 73,440 カラムに関する情報を格納
role 64 9 576 ロールに関する情報を格納
inherits 64 5 320 継承階層に関する情報を格納
function 160 0 0 関数に関する情報を格納
replication 352 0 0 レプリケーションに関する情報を格納
replication_slots 208 0 0 レプリケーションスロットに関する情報を格納
setting 112 16 1,792 GUCに関する情報を格納
固定値の合計 98,576 固定値は約100キロバイト
可変値 database 256 (可変) 256 × (可変) データベースに関する情報を格納
tablespace 208 (可変) 208 × (可変) データベーススペースに関する情報を格納
schema 96 (可変) 96 × (可変) スキーマに関する情報を格納
table 336 (可変) 336 × (可変) テーブルに関する情報を格納
index 240 (可変) 240 × (可変) インデックスに関する情報を格納
column 160 (可変) 160 × (可変) カラムに関する情報を格納
role 64 (可変) 64 × (可変) ロールに関する情報を格納
inherits 64 (可変) 64 × (可変) 継承階層に関する情報を格納
function 160 (可変) 160 × (可変) 関数に関する情報を格納
replication 352 (可変) 352 × (可変) レプリケーションに関する情報を格納
replication_slots 208 (可変) 208 × (可変) レプリケーションスロットに関する情報を格納
setting 112 (可変) 112 × (可変) GUCに関する情報を格納(xxx.confファイルに設定されたものと環境変数で設定されたものが統計対象)
可変値の合計 可変値のため合計も可変
  • 注1
    オブジェクト1個のサイズです。
  • 注2
    postgresql.confのパラメーター(pg_statsinfo.excluded_dbnamesなど)がデフォルト値の場合です。
  • 注3
    基本サイズにオブジェクト数を掛けた値です。

ポイント

可変値の各オブジェクト数についての確認方法を以下に示します。データベ-スクラスタ単位に確認するものと、データベ-ス単位に確認するものがあります。

確認単位 構成要素 確認方法(注4
データベースクラスタ単位 database SELECT count(d.oid) FROM pg_database d WHERE datallowconn AND d.oid >= 16384;
tablespace SELECT count(oid) FROM pg_tablespace WHERE oid >= 16384;
role SELECT count(oid) FROM pg_roles where oid >= 16384;
replication SELECT count(pid) FROM pg_stat_replication;
replication_slots SELECT count(slot_name) FROM pg_replication_slots;
setting SELECT count(name) FROM pg_settings WHERE source NOT IN ('client', 'default', 'session') AND setting <> boot_val;
データベース単位 schema SELECT count(oid) FROM pg_namespace WHERE oid >= 16384;
table SELECT count(c.oid) FROM pg_class c LEFT JOIN pg_index i ON c.oid = i.indrelid LEFT JOIN pg_class t ON c.reltoastrelid = t.oid LEFT JOIN pg_index x ON c.reltoastrelid = x.indrelid LEFT JOIN pg_namespace n ON c.relnamespace = n.oid WHERE c.relkind IN ('r', 't') AND c.oid >= 16384;
index SELECT count(x.indexrelid) FROM pg_class c JOIN pg_index x ON c.oid = x.indrelid JOIN pg_class i ON i.oid = x.indexrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 't') AND x.indexrelid >= 16384;
column SELECT count(attname) FROM pg_attribute a LEFT JOIN pg_class c ON a.attrelid = c.oid LEFT JOIN pg_statistic s ON a.attnum = s.staattnum AND a.attrelid = s.starelid AND NOT s.stainherit LEFT JOIN pg_namespace n ON c.relnamespace = n.oid WHERE a.attnum > 0 AND c.relkind IN ('r', 't') AND c.oid >= 16384;
inherits SELECT count(i.inhrelid) FROM pg_inherits i JOIN pg_class c ON i.inhrelid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid WHERE i.inhrelid >= 16384;
function SELECT count(oid) FROM pg_proc WHERE oid >= 16384;
  • 注4
    確認方法の「16384」は、OID(オブジェクト識別子)でPostgreSQLが内部で管理する値です。ユーザーが作成するオブジェクトのOIDは「16384」以降が採番されます。詳細については、PostgreSQL 12.0文書の「69.2.2 OIDの割当」を参照してください。

見積もり式

見積もり方法は2つあります。運用前に必要な容量をおおまかに見積もりたい場合は「概算見積もり式」をご利用ください。業務要件やデータベース、テーブル数などが明確で可変要素の変動が少ない場合は「詳細見積もり式」をご利用ください。

概算見積もり式

pg_statsinfoに同梱されているマニュアルに、スナップショットのサイズに関する記載があります。そこには「スナップショットのサイズは、DB内のオブジェクト数に依存しますが、概ね1回のスナップショットで1DBあたり600 - 800KBを消費します。デフォルトの取得間隔(10分間隔)の場合、監視対象インスタンス一つあたり1日で90 - 120MBを消費します。」と書かれています。

マニュアルに掲載されているスナップショットのサイズに関する記述

1回のスナップショットで1データベースあたりのサイズを最大の「約800キロバイト」と見積もる場合は、以下の式になります。

800キロバイト × データベース数 × (スナップショットの保持時間 ÷ スナップショットの取得間隔)

【例】

「概算見積もり式」を使って見積もってみます。pg_statsinfoの設定値は、以下とします。

設定項目 postgresql.confのパラメーター名
データベース数 2  
スナップショットの取得間隔(分) 10min(デフォルト値) pg_statsinfo.snapshot_interval
スナップショットの保持期間(日) 7(デフォルト値) pg_statsinfo.repository_keepday
自動メンテナンス機能 on(デフォルト値) pg_statsinfo.enable_maintenance
800キロバイト × 2 × (7 × 24 × 60 ÷ 10) ÷ 1024 = 約1,575メガバイト

詳細見積もり式

表1.におけるスナップショットのサイズについて固定値と可変値を使って見積もる場合は、以下の式になります。

(固定値 + 可変値) × (スナップショットの保持時間 ÷ スナップショットの取得間隔)

【例】

「詳細見積もり式」を使って見積もってみます。pg_statsinfoの設定値は、以下とします。

設定項目 postgresql.confのパラメーター名
固定値 約100キロバイト
可変値 データベースクラスタ単位 約5キロバイト
データベース単位 約828キロバイト
スナップショットの取得間隔(分) 10min(デフォルト値) pg_statsinfo.snapshot_interval
スナップショットの保持期間(日) 7(デフォルト値) pg_statsinfo.repository_keepday
自動メンテナンス機能 on(デフォルト値) pg_statsinfo.enable_maintenance
(100 + 5 + 828) × (7 × 24 × 60 ÷ 10) ÷ 1024 = 約918メガバイト

補足

pg_statsinfoの自動メンテナンス機能を使用することで、保持期間を経過した古いスナップショットは自動的に削除されます。上記例では、自動メンテナンス機能が作動しているため、最大7日分のスナップショットを見積もっています。

運用中のサイズ調整

運用中にスナップショットのサイズを確認したり、手動で古いスナップショットを削除したりすることもできます。

運用中のスナップショットのサイズ確認

スナップショットの情報は、pg_statsinfoのコマンドを使うことにより、リポジトリーDBに保存されたスナップショットの情報をテキスト形式で標準出力に表示します。以下を実行すると、スナップショットの総サイズが確認できます。

$ pg_statsinfo -h localhost -d repo -s

実行結果は以下の画面キャプチャー例のような形で表示されます。

pg_statsinfoコマンドの実行結果

取得サイズの変更

運用前の見積もりよりもスナップショットのサイズが大きい傾向が見られた場合は、以下の対処を実施することで、容量を削減できます。postgresql.confのパラメーター値を変更して、PostgreSQLを再起動してください。

  • スナップショットの取得間隔(pg_statsinfo.snapshot_interval)の値を長く変更する。
  • スナップショットの保持期間(pg_statsinfo.repository_keepday)の値を短く変更する。

古いスナップショットの強制削除

古いスナップショットを強制的に削除したい場合は、pg_statsinfoの関数を使って手動で削除してください。

【例】

取得日時が2021-04-01 17:00:00より古いスナップショットを削除する場合は以下を実行します。

$ psql -d mydb -c "SELECT statsinfo.maintenance('2021-04-01 17:00:00'::timestamptz);"

特定のスナップショットの強制削除

特定のスナップショットを強制的に削除したい場合は、pg_statsinfoのコマンドを使って手動で削除してください。

【例】

スナップショット一覧で各スナップショットのサイズを確認し、SnapshotID 4を削除する場合は以下を実行します。

$ pg_statsinfo -h localhost -d repo -l
$ pg_statsinfo -h localhost -d repo -D 4

実行結果は以下の画面キャプチャー例のような形で表示されます。

特定のスナップショットの削除方法

pg_statsinfoを使ってシステムの監視を行う場合は、事前にスナップショットのサイズを正しく見積もって、業務を運用することをお勧めします。

参考

FUJITSU Software Enterprise Postgresでは、バージョン10からpg_statsinfoを同梱しています。本記事の見積もり式は、FUJITSU Software Enterprise Postgresに同梱されているpg_statsinfoにも適用できます。

2021年6月25日公開

オンデマンド(動画)セミナー

    • PostgreSQLに関連するセミナー動画を公開中。いつでもセミナーをご覧いただけます。
      • 【事例解説】運送業務改革をもたらす次世代の運送業界向けDXプラットフォームの構築
      • ハイブリッドクラウドに最適なOSSベースのデータベースご紹介

本コンテンツに関するお問い合わせ

お電話でのお問い合わせ

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。

ページの先頭へ