【実務・中級編】 WALレシーバープロセス – PostgreSQL

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の知識をどんどん共有していくから、楽しみに待っていてくれよ!

じゃあ、また!

コメント

タイトルとURLをコピーしました