データベース監視

メトリクス、スロークエリ、アラート設計

データベース監視は問題の早期検知パフォーマンス最適化が目的。 適切なメトリクス収集、スロークエリの追跡、効果的なアラート設計が重要です。

主要メトリクス

リソース使用率

  • CPU: DBサーバーのCPU使用率
  • メモリ: バッファプール使用率、空きメモリ
  • ディスクI/O: 読み書きスループット、IOPS
  • ディスク容量: 使用率、増加傾向

接続とクエリ

  • 接続数: アクティブ/アイドル/最大
  • QPS: 秒間クエリ数
  • TPS: 秒間トランザクション数
  • クエリレイテンシ: 平均/P95/P99

レプリケーション

  • ラグ: レプリケーション遅延(秒/バイト)
  • 状態: レプリカの接続状態
  • WAL/Binlog: 生成量、アーカイブ状況

ロックと待機

  • ロック待ち: 待機中のクエリ数
  • デッドロック: 発生頻度
  • 長時間トランザクション: 件数と継続時間

スロークエリの検出

PostgreSQL
sql
1-- スロークエリログ設定(postgresql.conf)
2log_min_duration_statement = 1000 -- 1秒以上のクエリをログ
3log_statement = 'none' -- 通常のステートメントはログしない
4
5-- pg_stat_statements 拡張(推奨)
6CREATE EXTENSION pg_stat_statements;
7
8-- 遅いクエリTop10
9SELECT
10 query,
11 calls,
12 mean_exec_time::numeric(10,2) AS avg_ms,
13 total_exec_time::numeric(10,2) AS total_ms,
14 rows
15FROM pg_stat_statements
16ORDER BY mean_exec_time DESC
17LIMIT 10;
18
19-- 現在実行中のクエリ
20SELECT pid, now() - pg_stat_activity.query_start AS duration, query
21FROM pg_stat_activity
22WHERE state = 'active' AND query NOT LIKE '%pg_stat_activity%'
23ORDER BY duration DESC;
MySQL
sql
1-- スロークエリログ設定(my.cnf)
2slow_query_log = 1
3slow_query_log_file = /var/log/mysql/slow.log
4long_query_time = 1
5
6-- performance_schema から遅いクエリ
7SELECT
8 DIGEST_TEXT,
9 COUNT_STAR,
10 AVG_TIMER_WAIT/1000000000 AS avg_ms,
11 SUM_TIMER_WAIT/1000000000 AS total_ms
12FROM performance_schema.events_statements_summary_by_digest
13ORDER BY AVG_TIMER_WAIT DESC
14LIMIT 10;
15
16-- 現在実行中のクエリ
17SHOW PROCESSLIST;
18-- または
19SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';

監視用クエリ

PostgreSQL 監視クエリ
sql
1-- データベースサイズ
2SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname))
3FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;
4
5-- テーブルサイズ
6SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
7FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC;
8
9-- インデックス使用状況
10SELECT relname, idx_scan, seq_scan,
11 CASE WHEN seq_scan > 0 THEN idx_scan::float / seq_scan ELSE 0 END AS ratio
12FROM pg_stat_user_tables ORDER BY seq_scan DESC;
13
14-- 接続数
15SELECT count(*), state FROM pg_stat_activity GROUP BY state;
16
17-- キャッシュヒット率(目標: 99%以上)
18SELECT
19 sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS cache_hit_ratio
20FROM pg_statio_user_tables;
21
22-- レプリケーションラグ
23SELECT client_addr, state,
24 pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes
25FROM pg_stat_replication;

アラート設計

アラートはアクショナブルであるべき。 アラート疲れを避け、本当に対応が必要なものだけを通知する。

メトリクスWarningCritical
CPU使用率80%(5分継続)95%(5分継続)
ディスク使用率75%90%
接続数max_connections の 80%max_connections の 95%
レプリケーションラグ30秒60秒
長時間クエリ5分15分
デッドロック-発生時

監視ツール

汎用監視

  • Prometheus + Grafana: メトリクス収集と可視化
  • Datadog: SaaSモニタリング
  • CloudWatch: AWS環境

DB専用

  • pgwatch2: PostgreSQL専用
  • PMM: Percona Monitoring (MySQL)
  • MongoDB Atlas: MongoDB専用
Prometheus postgres_exporter
yaml
1# docker-compose.yml
2services:
3 postgres-exporter:
4 image: prometheuscommunity/postgres-exporter
5 environment:
6 DATA_SOURCE_NAME: "postgresql://user:pass@postgres:5432/mydb?sslmode=disable"
7 ports:
8 - "9187:9187"
9
10# prometheus.yml
11scrape_configs:
12 - job_name: 'postgres'
13 static_configs:
14 - targets: ['postgres-exporter:9187']

SRE/インフラ観点

ダッシュボード設計

  • Overview: 全DBの健全性サマリ
  • Detail: 個別DBの詳細メトリクス
  • Query: スロークエリ分析
  • Capacity: リソース使用傾向

トラブルシューティング

  • • CPU高騰 → スロークエリ、インデックス不足
  • • 接続枯渇 → コネクションリーク、プールサイズ
  • • ディスクI/O → バッファプールサイズ、クエリ最適化
  • • レプリカ遅延 → 書き込み負荷、ネットワーク

ベストプラクティス

  • • 本番と同等の監視をステージングにも
  • • 変更前後でメトリクスを比較
  • • 定期的にアラート閾値を見直し
  • • インシデント後のポストモーテムで改善