PostgreSQLの心臓部!WALレシーバープロセスを徹底解剖
やあ、みんな!今日はPostgreSQLの、ちょっと地味だけどめちゃくちゃ重要な「WALレシーバープロセス」について、現場の先輩エンジニアの視点から、分かりやすく解説していくよ。
「WALレシーバー?名前からして難しそう…」って思ったかもしれないけど、大丈夫!この子のおかげで、データベースの可用性やデータ保全がぐっと高まるんだ。まさに、縁の下の力持ちってやつさ。
そもそもWALって何だっけ?
WALレシーバーの話に入る前に、まずは「WAL」について軽くおさらいしておこう。WALは「Write-Ahead Logging」の略で、PostgreSQLがデータの変更をディスクに書き込む前に、その変更内容を「WALログ」というファイルに記録する仕組みのこと。
これがあるおかげで、
- クラッシュからの復旧: 万が一、サーバーが予期せず停止しても、WALログを再生すれば、失われたデータを復元できる。
- レプリケーション: プライマリサーバーで発生した変更を、スタンバイサーバーに伝えるための基盤になる。
このWAL、PostgreSQLの信頼性を支える超重要機能なんだ。
WALレシーバープロセス:スタンバイサーバーの「受信係」
さて、本題のWALレシーバープロセスだよ。この子は、主にスタンバイサーバーで動いているプロセスなんだ。
役割はシンプルだけど、めちゃくちゃ大事。
- プライマリサーバーからWALデータを受け取る。
- 受け取ったWALデータを、スタンバイサーバーのローカルなWALファイル(`pg_wal`ディレクトリ)に書き込む。
つまり、プライマリサーバーで起きた「出来事」を、リアルタイムでスタンバイサーバーに「伝達」してくれる、まさに「受信係」なんだ。
なんで「レシーバー」って名前なの?
そのまんまなんだけど、プライマリサーバーからWALデータを「受信(receive)」するから、WALレシーバーって呼ばれてるんだ。
どこで動いてるの?
スタンバイサーバー側で動いているプロセスだよ。プライマリサーバー側には、WALデータを送信する「WAL送信者プロセス(`wal_sender`)」があって、WALレシーバーはその「wal_sender」と通信しているイメージだね。
具体的な仕組み:どうやってWALデータを受け取るの?
WALレシーバーは、プライマリサーバーの`wal_sender`プロセスとネットワーク経由で通信するんだ。
1. WALレシーバーは、プライマリサーバーの`wal_sender`プロセスに対して、「この時点までのWALデータが欲しい!」とリクエストを送る。
2. `wal_sender`プロセスは、リクエストされたWALデータ(WALセグメントファイルの中身)をネットワークで送信する。
3. WALレシーバーは、受け取ったWALデータを自分のローカルのWALディレクトリ(`pg_wal`)に書き込む。
このやり取りを、プライマリサーバーでWALデータが生成されるたびに繰り返しているんだ。
レプリケーションのタイプによる違い
WALレシーバーがWALデータを受け取る方法は、レプリケーションのタイプによって少し違いがある。
- ストリーミングレプリケーション:
- WALレシーバーは、プライマリサーバーからWALデータを「ストリーム」で受け取る。
- ネットワーク帯域を効率的に使い、リアルタイムに近いデータ同期が可能。
- これが一番一般的で、現代のPostgreSQLレプリケーションの主流だね。
- ファイルベースのレプリケーション(やや古い手法):
- WALレシーバーは、プライマリサーバーからWALセグメントファイル(`.wal`ファイル)を定期的に取得する。
- ストリーミングレプリケーションに比べると、遅延が発生しやすい。
一般的には、ストリーミングレプリケーションを使うことが多いから、WALレシーバーは「リアルタイムでWALデータをストリームで受け取って、ローカルに書き込む」というイメージでOK。
実際の使用例:こんな時に活躍!
WALレシーバープロセスは、主に以下の場面で活躍するよ。
1. 冗長化・高可用性構成(HA構成)
これが一番よくあるケースだね。
- プライマリサーバーで障害が発生したら、スタンバイサーバーに切り替える(フェイルオーバー)。
- この時、スタンバイサーバーが最新のWALデータまで同期できていないと、データが失われてしまう可能性がある。
- WALレシーバーがプライマリからWALデータを継続的に受信・書き込みしてくれるおかげで、スタンバイサーバーは常にプライマリに追随できている。
- だから、フェイルオーバーしても、失われるデータが最小限(あるいはゼロ)に抑えられるんだ。
2. バックアップ・リカバリ
WALレシーバーの役割は、障害復旧やHA構成だけじゃない。
- 例えば、`pg_basebackup`でベースバックアップを取った後、そのバックアップを最新の状態に保つために、WALアーカイブとWALレシーバーを組み合わせることもある。
- WALアーカイブは、WALセグメントファイルが一杯になったら、それをどこか別の場所にコピーしておく仕組み。
- WALレシーバーは、アーカイブされたWALファイルや、プライマリから直接送られてくるWALデータを、スタンバイサーバーに適用していく。
3. タイムトラベルデバッグ(`pg_waldump`との連携)
ちょっとマニアックな話だけど、WALレシーバーが書き込んだWALファイルは、`pg_waldump`というツールで中身を確認できるんだ。
- `pg_waldump`は、WALファイルの内容を人間が読める形式(SQL文やコマンド)にダンプしてくれる。
- これにより、「いつ、どんなデータが、どのように変更されたのか」という履歴を追跡できる。
- これは、原因不明のデータ不整合を調査したり、デバッグしたりする際に、非常に強力な武器になるんだ。
設定ファイルでの確認方法
WALレシーバープロセス自体は、直接設定する項目は少ないんだけど、その動作を左右する設定はいくつかある。
まず、レプリケーションが有効になっているか確認するには、プライマリサーバーの`postgresql.conf`で以下の設定を確認しよう。
postgresql.conf (プライマリサーバー側)
wal_level = replica # または logical
max_wal_senders = 5 # 同時にWAL送信を許可する数(WALレシーバーの数に対応)
- `wal_level`: レプリケーションに必要な情報までWALに記録するように設定する。`replica`以上が必要。
- `max_wal_senders`: プライマリサーバーが同時にWAL送信できる`wal_sender`プロセスの最大数。スタンバイサーバーの数に応じて増やす必要があるよ。
次に、スタンバイサーバー側では、`postgresql.conf`と`recovery.conf`(PostgreSQL 9.6以前)または`postgresql.conf`(PostgreSQL 10以降)でレプリケーションの設定を行う。
PostgreSQL 10 以降の場合 (`postgresql.conf`で設定)
postgresql.conf (スタンバイサーバー側)
primary_conninfo = ‘host=your_primary_host port=5432 user=replication_user password=your_password’
hot_standby = on # 読み取り専用クエリを許可する場合
- `primary_conninfo`: プライマリサーバーへの接続情報を記述する。ここに接続情報があれば、WALレシーバープロセスが自動的に起動し、プライマリに接続してWALデータの受信を開始するんだ。
PostgreSQL 9.6 以前の場合 (`recovery.conf`で設定)
recovery.conf (スタンバイサーバー側)
standby_mode = on
primary_conninfo = ‘host=your_primary_host port=5432 user=replication_user password=your_password’
- `standby_mode = on`: スタンバイモードで起動することを指示。
- `primary_conninfo`: 同上。
これらの設定をしてPostgreSQLを再起動すれば、スタンバイサーバー上でWALレシーバープロセスが自動的に動き出す。
プロセス確認方法
実際にWALレシーバープロセスが動いているか確認するには、以下のコマンドを使うのが便利だよ。
- `ps aux | grep walreceiver`: Linux/macOSのコマンド。プロセス一覧から`walreceiver`という文字列を含む行を絞り込む。
- `SELECT FROM pg_stat_activity WHERE backend_type = ‘walreceiver’;`: PostgreSQLのSQLインターフェースから確認。
`pg_stat_activity`で確認すると、WALレシーバーの状態(`waiting for WAL to be received`, `streaming WAL from primary`など)も確認できて、レプリケーションの状況を把握しやすいんだ。
例えば、こんな風に見えるはずだよ。
pid | datid | datname | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | xact_start | query_start | state_change | wait_event_type | wait_event | state | backend_xid | backend_xmin | backend_type
—–+——-+———+———-+———-+——————+————-+—————–+————-+—————+————+————-+———————+—————–+————+—————+————-+————–+————–
1234| 16384 | postgres| 10 | repluser | walreceiver | 192.168.1.10| | 5432 | … | | | 2023-10-27 10:00:00 | ClientRead | | streaming WAL | | | walreceiver
`application_name`が`walreceiver`になっているのがポイントだね。`client_addr`にはプライマリサーバーのアドレスが表示されるはずだよ。
トラブルシューティングのヒント
WALレシーバーでよくある問題とその対処法をいくつか紹介しておくね。
- レプリケーション遅延(Lag):
- 原因: ネットワーク帯域不足、プライマリサーバーの負荷、スタンバイサーバーのディスクI/O遅延など。
- 対処法: ネットワーク帯域の確認、プライマリ・スタンバイ両方のリソース監視、ディスクI/Oのボトルネック解消。
- 確認: `pg_stat_replication`ビューで`write_lag`や`flush_lag`を見る。
- WALレシーバーが起動しない・切断される:
- 原因: `primary_conninfo`の設定ミス(ホスト名、ポート、ユーザー名、パスワード)、ファイアウォール、プライマリサーバーの`max_wal_senders`不足、ネットワーク障害。
- 対処法: 設定ファイルの確認、ファイアウォール設定の確認、`max_wal_senders`の増加、ネットワーク疎通確認。
- 確認: PostgreSQLのログ(`log_directory`に設定された場所)にエラーメッセージが出力されているはず。
- WALファイルが一杯になる:
- 原因: WALレシーバーがWALデータをうまく受信・書き込みできていないため、プライマリサーバー側でWALファイルが溜まってしまう。
- 対処法: 上記の「レプリケーション遅延」や「起動しない」場合の対処法を試す。
- 注意: WALファイルが一杯になると、プライマリサーバーのデータ書き込みができなくなり、サービス停止につながる可能性がある!早期発見・対処が超重要。
まとめ:WALレシーバーは信頼性の要!
どうだったかな?WALレシーバープロセスは、普段は意識すること少ないかもしれないけど、PostgreSQLのレプリケーション、ひいてはデータベース全体の信頼性と可用性を支える、まさに「要」なんだ。
- プライマリからWALデータを受け取り、スタンバイに書き込む「受信係」。
- ストリーミングレプリケーションでリアルタイム同期を実現。
- HA構成やバックアップリカバリで大活躍。
- 設定ミスやネットワーク問題に注意が必要。
もし君がPostgreSQLでレプリケーションを組んでいるなら、このWALレシーバープロセスがちゃんと動いているか、定期的にチェックすることをおすすめするよ。何かあった時のためにも、仕組みを理解しておくと、いざという時に慌てずに済むからね。
これからも、現場で役立つPostgreSQLの知識をどんどん共有していくから、楽しみに待っていてくれよ!
じゃあ、また!
コメント