どんな複雑なシステムでもそうだけど、PostgreSQLでも何かうまくいかないことがあるよね:クエリがめっちゃ遅かったり、サーバーの負荷が上がったり、ユーザーがイライラし始めたり。ログ記録は、データベースの中で何が起きてるか観察する方法なんだ。例えば:
- 遅いクエリを見つける — アプリの動きを遅くしてるやつ。
- パフォーマンスを最適化する — クエリの動きを分析して改善する。
- エラーを診断する — 制約違反とか、文法ミスとか。
- 監査を確保する — 誰がどんな操作をサーバーでやったか追跡する。
ログ記録の主なパラメータ
PostgreSQLの設定ファイル(postgresql.conf)には、ログ記録に関するパラメータがたくさんある。ここで一番大事なやつを見ていこう。
log_statement— SQLクエリのログ記録
log_statementパラメータは、どのSQLクエリをログに記録するか決めるやつ。値はこんな感じ:
none— クエリのログ記録をオフにする。ddl— データ定義コマンドだけログ(例:CREATE、ALTER、DROP)。mod— データを変更するコマンド全部ログ(例:INSERT、UPDATE、DELETE)。all— 全てのSQLクエリをログ(シンプルなSELECTも含む)。
例:
全部のクエリをログしたいなら、postgresql.confでこう設定しよう:
log_statement = 'all'
データ変更コマンドだけログしたいなら:
log_statement = 'mod'
設定を変えたら、サーバーの再起動を忘れずに:
sudo systemctl restart postgresql
log_duration— 実行時間のログ記録
log_durationパラメータは、各クエリの実行時間をログに記録できる。どのクエリが一番時間かかってるか知りたいときに便利。
例:
クエリの実行時間をログしたいなら:
log_duration = on
遅いクエリだけログしたいなら、log_min_duration_statementを使おう(これは後で説明するよ)。
log_min_duration_statement— 遅いクエリのログ記録
このパラメータは、指定した時間(ミリ秒)より長くかかったクエリだけログに記録する。データベースの「ボトルネック」を見つけるのに超便利。
例:
1秒以上かかったクエリをログしたい場合:
log_min_duration_statement = 1000
全てのクエリを実行時間に関係なくログしたいなら、値を0に:
log_min_duration_statement = 0
-1にすると、この機能はオフになるよ。
log_line_prefix— ログメッセージの構造
log_line_prefixパラメータは、ログメッセージのフォーマットをカスタマイズできる。例えば、ユーザー名やPID、日時を追加したりできるよ。
例:
ユーザー名、データベース名、時間、プロセスを記録したいなら:
log_line_prefix = '%t [%p]: [%d]: [%u]: '
それぞれの意味:
%t— クエリの時間。%p— プロセスのPID。%d— データベース名。%u— ユーザー名。
全オプションのリストは:PostgreSQLドキュメント。
logging_collector— ログコレクター
logging_collectorパラメータは、ログをファイルに書き出す仕組みをオンにする。オフだと、ログは標準出力(stdout)だけに出るからちょっと不便。
ログコレクターを有効にするには:
logging_collector = on
log_directoryとlog_filenameでログファイルのパスも指定しよう:
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d.log'
パラメータの実践的な使い方
実際のシナリオでログ記録パラメータをどう使うか見てみよう。
シナリオ1: 全クエリのログ記録
新しいデータベースで何が起きてるか全部見たいなら、こう設定しよう:
log_statement = 'all'
log_line_prefix = '%t [%p]: [%d]: [%u]: '
これで、データベースで実行される全てのクエリがログファイルに記録されるよ。デバッグに便利!
シナリオ2: 遅いクエリの特定
サーバーがたまに「重い」と感じたら、問題のクエリを見つけるためにこう設定しよう:
log_min_duration_statement = 500 # 500msより長いクエリをログ
log_line_prefix = '%t [%p]: [%d]: [%u]: [%r] '
%rはクライアントのIPアドレスを追加する。これで、サーバーを重くしてるクエリを簡単に見つけられる。
シナリオ3: 最小限のログモード
サーバーが安定してて、監査用に最低限のログだけ欲しい場合:
log_statement = 'mod'
log_duration = off
これだと、データ変更(INSERT、UPDATEなど)だけログされる。
ログの分析
ログがデータでいっぱいになったら、分析できることが大事!例えば:
テキストエディタでログファイルを開く:
cat /var/log/postgresql/postgresql.log
分析ツールを使う。例えばgrepで遅いクエリを探す:
grep "duration: " /var/log/postgresql/postgresql.log
もっと高度なログ分析ツールもあるよ。例えばpgBadger。
便利なアドバイス
ログを細かくしすぎるとディスク負荷が上がるから、本番環境では必要なパラメータだけ使おう。
古いログファイルは定期的に消すかアーカイブして、ディスクがいっぱいにならないようにしよう。
ログ記録は、必要なデータだけ集めるパラメータでやるのが効率的。例えばlog_min_duration_statementは、ピンポイントでリソースを節約できる。
どう?これでPostgreSQLのログ記録設定も、クエリ分析やパフォーマンスアップもバッチリだね。ある(いや、何人もいる)有名じゃないけどイイ開発者が言ったように:「ログはクエリの過去を見て、データベースの未来を直すチャンスだよ」。
GO TO FULL VERSION