こんにちは!オブザーバビリティの世界へようこそ。
システム全体の監視を一手に引き受ける「Zabbix」。皆さんのインフラストラクチャの心臓部を支える頼もしい相棒ですが、ここで一つ、エンジニアなら誰もが一度は冷や汗をかく「究極のジレンマ」について考えてみましょう。
「監視ツールであるZabbixを支えているデータベース自身が死んだとき、いったい誰がそれを検知するのか?」
今回は、Zabbixのバックエンドデータベース(今回はモダンな現場で選ばれることの多い PostgreSQL をピックアップします)の死活監視と、システム停止を未然に防ぐための高精度なストリーミングレプリケーション遅延のメトリクス化について、現場の生きた知見を交えて徹底解説します。
これをマスターすれば、「データベースのサイレント障害」に怯える夜とはおさらばできますよ。さあ、一緒に本物の監視アーキテクチャを作り上げていきましょう!
—
1. なぜZabbixのバックエンドDBを守る必要があるのか?
Zabbixサーバーは、エージェントからのデータやSNMPトラップをかき集め、内部のデータベースにガンガン書き込み続けます。つまり、Zabbixのパフォーマンスと安定性は、そのままバックエンドDBの健康状態に依存しているのです。
特に、HA(高可用性)構成をとるためにPostgreSQLのストリーミングレプリケーション(プライマリ/スタンバイ構成)を組んでいる環境は多いはずです。ここでよくある失敗が、「プライマリが落ちたらスタンバイに切り替わるから安心」という油断。
- レプリケーションが知らぬ間に数ギガバイト遅延していた。
- フェイルオーバーした瞬間に、古いデータが溢れてスプリットブレイン(調停不能)を起こした。
- Zabbix自身がDBのダウンに巻き込まれ、アラートすら飛ばせずに沈黙した。
こうした悲劇を防ぐためには、「Zabbixの内側からの監視」と「外側からの独立した監視」の二段構えが絶対に必要です。
—
2. PostgreSQLレプリケーション遅延を正確にメトリクス化する
「レプリケーション遅延」と一言で言っても、単に「時間(ラグ)」を見るだけでは不十分です。ネットワークの一時的な詰まりと、トランザクションの巨大な処理遅滞を切り分けるために、「遅延バイト数(Byte Lag)」と「遅延時間(Time Lag)」の双方向からアプローチするのが、プロのオブザーバビリティ設計です。
以下のSQLクエリを、監視対象のPostgreSQL(プライマリ側)に対して実行することで、ミリ秒単位・バイト単位の正確な遅延を抽出できます。
正確な遅延測定クエリ(PostgreSQL 10以降対応)
SELECT
application_name,
client_addr,
state,
sync_state,
— バイト単位の遅延計算(WALの書き込み位置の差分)
(pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn)) AS write_lag_bytes,
(pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn)) AS flush_lag_bytes,
(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag_bytes,
— 時間単位の遅延計算(スタンバイ側で最後にリプレイされたトランザクションの経過時間)
EXTRACT(EPOCH FROM (now() – backend_xmin)) AS xmin_age_seconds
FROM
pg_stat_replication;
> 💡 先輩からのワンポイントアドバイス
> このクエリの中で最も注目すべきは `replay_lag_bytes` です。これが右肩上がりに増え続けている場合、スタンバイ側が重い処理(大量のインデックス作成やバッチ処理など)で追いつかなくなっている明確なサインです。この数値をZabbixのカスタムアイテムとして取り込みましょう。
—
3. Zabbix自身が検知できなくなるジレンマを防ぐ「外部死活監視」の設計
冒頭のジレンマ、「Zabbixが死んだら誰が気づくのか?」を解決する唯一にして最善の解は、「Zabbixの外部(サードパーティ製、あるいは別系統の軽量スクリプト)から、ZabbixとDBの生死を監視する」ことです。
ここでは、複雑なツールを新たに導入する前に、Linuxの標準機能や超軽量なシェルスクリプトを組み合わせた、最も堅牢でシンプルな外部監視の設計手法を伝授します。
堅牢な外部監視スクリプトの例(Bash)
このスクリプトを、Zabbixサーバーとは別の監視サーバー(あるいはクラウドの可用性チェッカー等)からCronなどで定期実行します。
!/bin/bash
==============================================================================
Script Name: check_zabbix_db_health.sh
Description: ZabbixおよびバックエンドPostgreSQLの生死を外部から直接叩いて確認する
==============================================================================
DB_HOST=”zabbix-db-primary.internal”
DB_USER=”zabbix”
DB_NAME=”zabbix”
ALERT_WEBHOOK_URL=”https://hooks.slack.com/services/YOUR/WEBHOOK/URL”
1. PostgreSQLへの直接接続テスト(TCP接続 & 簡単なクエリ実行)
pg_isready -h “$DB_HOST” -U “$DB_USER” > /dev/null 2>&1
if [ $NE -ne 0 ]; then
echo “[CRITICAL] PostgreSQL is unreachable!”
# ここでSlackやPagerDutyへ緊急通知を飛ばす
exit 2
fi
2. レプリケーション遅延が閾値(例: 1GB以上)を超えていないかチェック
(先ほどのSQLをワンライナーで実行)
LAG_BYTES=$(psql -h “$DB_HOST” -U “$DB_USER” -d “$DB_NAME” -t -c \
“SELECT COALESCE(MAX(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)), 0) FROM pg_stat_replication;”)
THRESHOLD_BYTES=1073741824 # 1GB
if [ “$LAG_BYTES” -gt “$THRESHOLD_BYTES” ]; then
echo “[WARNING] Replication lag is too high: ${LAG_BYTES} bytes”
# 警告通知の処理
exit 1
fi
echo “[OK] Zabbix DB and Replication are healthy.”
exit 0
なぜこの設計が最強なのか?
1. 依存関係の断絶: Zabbixアプリが完全にフリーズしていようが、OSのカーネルが生きていれば、このスクリプトは正確にデータベースの異常をキャッチして外部(Slackやメール)へ叫んでくれます。
2. ノイズの排除: Zabbixの内部キューが詰まってアラートが遅延する現象を完全に回避できます。
—
まとめ:監視の信頼性をデザインしよう
今回は、ZabbixのバックエンドであるPostgreSQLを守るための死活監視と、高精度なレプリケーション遅延のメトリクス化、そして監視のジレンマを突破する外部監視設計について解説しました。
- データベースの健康は、監視システムの命であること。
- 単なる死活だけでなく、WALの差分(バイト単位)でレプリケーション遅延を正確に捉えること。
- Zabbixの外側から守る仕組みを必ずワンセットで用意すること。
これを現場に導入するだけで、障害発生時の初動対応スピードが劇的に変わり、「頼れるインフラエンジニア」としての信頼がグッと高まります。
日々の運用監視を少しずつアップデートして、安心できるシステムライフを手に入れましょう!それではまた、次の現場でお会いしましょう。