この記事は PostgreSQL アドベントカレンダー の25日目です。
基本的なPostgreSQLのモニタリングについては下記に纏めました。
本日はここで扱っていないレプリケーションの監視についてまとめようと思います。
なおPostgreSQLのストリーミング・レプリケーション (Streaming Replication) は、PostgreSQL 9.0 移行に使える機能です。
本ブログで説明するレプリケーションはこのストリーミング・レプリケーションを対象とします。
そのためここでは8.4とかで Slony-I
使ってるケースや pgpool-II
でレプリケーションモードを使ってるケースは対象外です。
レプリケーションの仕組み
PostgreSQLのレプリケーションは変更履歴であるWAL(ログ先行書き込み)を使っています。 概要や設定方法などは以下のスライドなどを見てください。
www.slideshare.net
Let's Postgres ストリーミング・レプリケーション
レプリケーションの設定方法や概要についてはいっぱい資料がでるので大丈夫だと思います。 ちなみにレプリケーションはバージョンによって結構設定ファイルが違うので自分が作りたいレプリケーションのバージョンをしっかり確認して作ってください。
レプリケーションスロット
レプリケーションの説明は多くは9.0 ~ 9.2くらいが多くて9.4から追加されたレプリケーションスロットの説明が少ないです。
www.slideshare.net
レプリケーションスロットのメリットは下記のとおりです。
レプリケーションのモニタリング
さてPostgreSQLのレプリケーションについての基礎知識は揃ったと思います。
そんなレプリケーションの状態を知る方法として統計情報の活用があります。
9.1 からある pg_stat_replication
と 9.6 からある pg_stat_wal_receiver
です。
pg_stat_replicationはプライマリ側から見たWALの送信状況(WAL sender)、pg_stat_wal_receiverを使えばスタンバイ側のWALの受信状況(WAL receiver)がわかります。
pg_stat_replication
pg_stat_replicationは接続中のスタンバイの一覧とその状況を確認できます。 項目については日本語ドキュメントを読みましょう。
前述のとおり、これはプライマリ側のサーバで見るものです。 注意点はドキュメントにもありますがカスケードレプリケーションしている孫の情報はありません。 それではレプリケーション状態にあるスタンバイがWALの受信が遅れているかを把握しましょう。 特に重要なのは下記の5つです。
項目名 | 説明 |
---|---|
state | スタンバイの状態 |
sent_location | プライマリが送信済みのWALの位置 |
write_location | スタンバイ側でバッファへ書き込み済みWALの位置 |
flush_location | スタンバイ側でディスクへ書き込み済みWALの位置 |
replay_location | スタンバイ側で再生済みのWAL位置 |
レプリケーションの状態を示すのが state
です
通常時は streaming
です。
項目名 | 説明 |
---|---|
startup | 接続の確立中 |
backup | pg_basebackup によるバックアップの実施中 |
catchup | 過去の更新を反映中 |
streaming | 更新をリアルタイムに反映中 |
更に *_location
と SELECT pg_current_xlog_location()
を比べるとレプリケーションの細かな状態がわかります。
例えば pg_current_xlog_location()
と sent_location
に大きな差がある場合には、転送するまでの遅延が発生していることがわかります。
このように転送以前が遅延するケースではプライマリ側の性能不足などが予想できます。
ちなみに蛇足ですがpg_stat_replicationの sync_state
ですが下記の状態があります。
項目名 | 説明 |
---|---|
async | 非同期モード |
sync | 同期モード |
potential | 現在は非同期モードだが上位のプライオリティを持つ別スタンバイが落ちた場合には、syncに格上げされます |
potential
は PostgreSQL 9.6未満の同期レプリケーションはスレーブ1台のみ有効だった時はよく見たけど今は複数設定できるので、見る機会は少ないかもしれません。
さて長々と書きましたが上記のことをそれとなく知るためのSQLがこちらです。
SELECT sent_location, write_location, flush_location, replay_location, pg_xlog_location_diff(sent_location, write_location) as send_diff_byte, pg_xlog_location_diff(sent_location, flush_location) as flush_diff_byte, pg_xlog_location_diff(sent_location, replay_location) as replay_diff_byte FROM pg_stat_replication;
ちなみに pg_xlog_location_diff()
はlocaltionの差分をいい感じバイト単位(本来は16進数で位置のみ)にしてくれるシステム関数ですが 9.2 からです。
さらに補足ですが10からはxlogはwalに統一されるので関数名が pg_wal_lsn_diff()
に変わります。
10にしたい人は @houseisland さんの 20日目の記事 「PostgreSQL10へのアップグレード前に押さえておきたい3つの注意点」 を読みましょう。
システム関数については本体の公式ドキュメントを参考にしてください。
このようにWALの転送状況を知ることでレプリケーションが正しく行えているかどうかを判断します。
pg_stat_wal_receiver
pg_stat_wal_receiverはスタンバイ側から接続中のプライマリの状況を確認できます。
pg_stat_wal_receiverは PostgreSQL 9.6 から追加された機能です。
最初に謝っておくけど そーだいさん、まだ9.6を本番運用したことがないんだ 正直すまんかった。
来年は絶対9.6使うからそのための自分のためのメモとしても調べた内容を書いておきます。
今までは スタンバイ側で最後に反映処理をした時間
を pg_last_xact_replay_timestamp()
を使って調べていました。
またWALの受信状況を知るためにには pg_last_xlog_receive_location()
を使っていました。
これらが全て pg_stat_wal_receiver
で包括してスタンバイから確認できるようになりました。
例えばプライマリ側のsent_location とスタンバイ側での pg_last_xlog_receive_location()
に大きな差がある場合は、ネットワークの遅延やスタンバイサーバの性能不足を疑えます。
このように pg_current_xlog_location()
と比較することで
- write_location: プライマリとスタンバイの書き込みは一致しているかどうか
- flush_location: プライマリとスタンバイのディスクは一致しているかどうか
- replay_location: プライマリとスタンバイで同じデータが参照できるかどうか
などがわかります。
これと同様が latest_end_lsn
で見れるようになりました。
pg_stat_replicationとpg_stat_wal_receiverを比べることで障害時などはより素早く対応することができます。
※ pg_stat_wal_receiverの情報全く出てこなかったから世の中で使われて無さそうだった
まとめ
レプリケーションについてみなさん如何でしたでしょうか。 PostgreSQLのレプリケーションはどんどん進化しています。 それに合わせて勿論モニタリングも改善していく必要があります。 9.xの時はこうだったから10の時も同じで良いとはいきません。 常に自分たちのモニタリングを育てていきましょう!! 私もpg_stat_wal_receiverの便利SQLも考えていきたいと思います。