背景とStreaming Replicationが必要な理由
皆さん、こんにちは!現代のテクノロジー環境では、データはあらゆるアプリケーションにとって極めて重要な役割を担っています。eコマースサイト、社内管理システム、モバイルアプリケーションのいずれを開発している場合でも、データが常に利用可能であり、失われないことを保証することが最優先事項です。
私はこれまでMySQL、PostgreSQL、MongoDBなど、多くのデータベースを扱ってきました。それぞれに独自の強みがあり、特定のニーズに適しています。しかし、どの選択肢であっても、予期せぬ障害から保護するための強力なデータ保護ソリューションが必要です。
想像してみてください。もしプライマリサーバーに障害が発生した場合、バックアップからのデータ復旧には数時間、場合によっては丸一日かかることがあります。その間、アプリケーションは停止します。これにより、eコマースサイトは毎時数億ドンの収益を失う可能性があり、ユーザーエクスペリエンスや信頼への悪影響は言うまでもありません。これが、高可用性(HA)と災害復旧(DR)ソリューションが非常に重要になる理由です。
PostgreSQL Streaming Replicationは、この課題を解決するための非常に効果的なソリューションです。定期的なバックアップだけに頼るのではなく、Streaming Replicationを使用すると、1つまたは複数のスタンバイサーバーをプライマリサーバーとほぼ瞬時に同期させることができます。
Primaryでのすべての変更は、継続的にStandbyに送信されます。これにより、Primaryに障害が発生した場合、Standbyは迅速に引き継ぎ、ダウンタイムを最小限に抑え、わずか数分、あるいは数十秒に短縮することができます。
このガイドでは、PostgreSQL Streaming Replicationのセットアップと構成をステップバイステップで実施します。目標は、継続的な運用を保証する堅牢なデータベースシステムを構築できるようにすることです。
インストール(環境準備)
構成の詳細に入る前に、環境を準備する必要があります。Primaryとして機能する1台とStandbyとして機能する1台の2台のLinuxサーバー(例:Ubuntu Server)が既にあると仮定します。両方のサーバーにPostgreSQLがインストールされている必要があります。
最小要件:
- 2台のLinuxサーバー(例:Ubuntu 22.04 LTS)。
- 両方のサーバーにPostgreSQLバージョン14以上がインストールされていること。
- PrimaryとStandby間のネットワーク接続。
UbuntuにPostgreSQLをインストールするには、次のコマンドを使用できます(まだインストールしていない場合):
sudo apt update
sudo apt install postgresql postgresql-contrib -y
PrimaryサーバーのIPアドレスを192.168.1.100、StandbyサーバーのIPアドレスを192.168.1.101と仮定します。これらのアドレスは、構成プロセス全体で使用します。
PostgreSQLサービスの確認:
両方のサーバーでPostgreSQLサービスが実行されていることを確認してください:
sudo systemctl status postgresql
サービスが実行されていない場合は、起動してください:
sudo systemctl start postgresql
同時に、PrimaryとStandby間でポート5432(PostgreSQLのデフォルトポート)をブロックするファイアウォールがないことを確認する必要があります。もしあれば、このポートを開く必要があります:
sudo ufw allow 5432/tcp
sudo ufw enable
注:以下のすべての設定コマンドは、postgresユーザー権限またはsudo -u postgresで実行されます。PostgreSQLのバージョンは14であるため、構成パスは/etc/postgresql/14/main/、データディレクトリは/var/lib/postgresql/14/main/になります。ご自身のPostgreSQLのバージョンに合わせて調整してください。
PostgreSQL Streaming Replicationの詳細な構成
これはこのガイドの中心であり、Streaming Replicationをセットアップするために構成ファイルをカスタマイズします。
3.1. Primaryサーバー(192.168.1.100)での構成
まず、Primaryサーバーを構成します。
ステップ1: postgresql.confの編集
PostgreSQLのメイン構成ファイルを開きます:
sudo nano /etc/postgresql/14/main/postgresql.conf
以下の行を見つけて編集(または追加)します:
-
listen_addresses: PostgreSQLがすべてのIPアドレスからの接続をリッスンできるようにするか、Standbyの特定のIPを指定します。listen_addresses = '*' -
wal_level: レプリケーションモードを有効にするには、この値はreplicaである必要があります。wal_level = replica -
max_wal_senders: WAL送信プロセスの最大数。持っているStandbyの数に対応できるように、この値を十分に大きく設定します(例:5-10)。max_wal_senders = 5 -
wal_keep_size: PrimaryがStandby用に保持するWALの容量(MB)。短時間接続が切断された後にStandbyが再同期できるように、十分に大きく設定します。1024(1GB)は良い開始点です。wal_keep_size = 1024 -
archive_mode: WALアーカイブモードを有効にします。これはPoint-In-Time Recovery (PITR) に役立ち、より安全なデータ保護を保証します。archive_mode = on -
archive_command: 完了したWALをコピーするコマンド。以下の例では、/var/lib/postgresql/14/main/archiveディレクトリにコピーします。このディレクトリを作成し、事前に権限を付与する必要があります:sudo mkdir -p /var/lib/postgresql/14/main/archive sudo chown -R postgres:postgres /var/lib/postgresql/14/main/archiveその後、
postgresql.confに追加します:archive_command = 'cp %p /var/lib/postgresql/14/main/archive/%f'
ステップ2: pg_hba.confの編集
pg_hba.confファイルはPostgreSQLへの接続認証を制御します。Standbyサーバーがレプリケーションユーザーを使用してPrimaryに接続できるようにする必要があります。
ファイルを開きます:
sudo nano /etc/postgresql/14/main/pg_hba.conf
ファイルの末尾に以下の行を追加し、192.168.1.101/32をStandbyサーバーのIPアドレスに置き換えます:
host replication repuser 192.168.1.101/32 scram-sha-256
ステップ3: レプリケーションユーザーの作成
Standbyが接続してデータを同期できるように、Primaryサーバーに特別なユーザーを作成する必要があります。
Primary上のpsqlコンソールにログインします:
sudo -u postgres psql
repuserユーザーをREPLICATION権限で作成し、パスワードを設定します:
CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT -1 ENCRYPTED PASSWORD 'your_secure_password_here';
\q
(your_secure_password_hereを強力なパスワードに置き換えてください。)
ステップ4: Primaryサーバーの再起動
設定変更を有効にするには、Primary上でPostgreSQLサービスを再起動する必要があります:
sudo systemctl restart postgresql
3.2. Standbyサーバー(192.168.1.101)での構成
次に、Standbyサーバーの構成に移ります。
ステップ1: Standby上のPostgreSQLサービスを停止
データをコピーする前に、Standby上のPostgreSQLが停止していることを確認してください:
sudo systemctl stop postgresql
ステップ2: 古いデータ(存在する場合)を削除
pg_basebackupを実行する前に、Standby上のデータディレクトリは空であるか、存在しない必要があります。PostgreSQLをインストールしていてデフォルトのデータがある場合は、削除してください:sudo rm -rf /var/lib/postgresql/14/main/*
ステップ3: Primaryからベースバックアップ(Base Backup)をコピー
pg_basebackupコマンドを使用して、PrimaryからStandbyにすべてのデータをコピーします。このコマンドはPrimary上のデータディレクトリの正確なコピーを作成し、レプリケーションに必要なpostgresql.auto.confファイルを自動的に生成します。
Standbyサーバーでこのコマンドを実行します:
sudo -u postgres pg_basebackup -h 192.168.1.100 -p 5432 -U repuser -D /var/lib/postgresql/14/main -F p -Xs -P -R -W
オプションの説明:
-h 192.168.1.100: PrimaryサーバーのIPアドレス。-p 5432: Primaryサーバーのポート。-U repuser: Primaryで作成したレプリケーションユーザー。-D /var/lib/postgresql/14/main: コピーされたデータを保存するためのStandby上のターゲットディレクトリ。-F p: 出力形式は「plain」(tar圧縮なし)。-Xs: バックアップに必要なWALファイルを含める。-P: コピーの進行状況を表示。-R:standby.signalファイルと、適切なprimary_conninfoを持つpostgresql.auto.confファイルを自動的に作成します。これは非常に便利なオプションです!-W:repuserユーザーのパスワードを要求。
コマンドを実行すると、Primaryで設定したrepuserのパスワードが要求されます。
ステップ4: Standby上のpostgresql.confを編集
pg_basebackupが完了すると、データディレクトリ内にpostgresql.auto.confファイルが自動的に作成されます。このファイルには重要なprimary_conninfo行が含まれています。ここで、postgresql.confに追加のパラメータを1つだけ調整する必要があります。
ファイルを開きます:
sudo nano /etc/postgresql/14/main/postgresql.conf
hot_standbyが有効になっていることを確認してください(このパラメータにより、Standbyが読み取りクエリを受け入れることができます):
hot_standby = on
ステップ5: Standbyサーバーの起動
Standby上でPostgreSQLサービスを起動し、Primaryへの接続と同期を開始します:
sudo systemctl start postgresql
これで、構成が完了しました!
レプリケーションの確認と監視
構成が完了したら、次にレプリケーションが期待通りに動作しているかを確認します。これは非常に重要なステップです。
4.1. Primaryサーバーでのレプリケーションステータスの確認
Primary(192.168.1.100)上のpsqlにpostgresユーザーでログインします:
sudo -u postgres psql -c "SELECT pid, usename, application_name, client_addr, state, sync_state, sync_priority, write_lag, flush_lag, replay_lag FROM pg_stat_replication;"
接続されているStandbyサーバーに関する詳細情報を含むテーブルが表示されます。いくつかの重要な列は次のとおりです:
usename: レプリケーションユーザー名(例:repuser)。application_name: 接続しているアプリケーションの名前。client_addr: StandbyサーバーのIPアドレス。state: レプリケーション接続の状態。streamingはすべてが正常に動作していることを意味します。sync_state: 同期状態。async(非同期)がデフォルトで、一般的に使用されます。write_lag,flush_lag,replay_lag: PrimaryとStandby間の遅延。理想的には、これらの値は非常に小さい(0に近い)か、0です。
行が表示されない場合や、状態がstreamingではない場合は、構成手順とPostgreSQLのエラーログを確認してください。
4.2. Standbyサーバーでのレプリケーションステータスの確認
Standby(192.168.1.101)上のpsqlにpostgresユーザーでログインします:
sudo -u postgres psql -c "SELECT status, receive_start_lsn, latest_end_lsn, latest_end_time, conninfo FROM pg_stat_wal_receiver;"
注意すべき列は次のとおりです:
status:wal receiverの状態。streamingは良い兆候です。latest_end_lsn: Standbyが最後に受信してリプレイしたLSN(ログシーケンス番号)の位置。latest_end_time: その最後のLSNの時刻。conninfo: Primaryへの接続情報。
4.3. 実際のデータ同期の確認
確認する最良の方法は、Primaryにデータを書き込み、それがStandbyに表示されるかどうかを確認することです。
Primaryサーバーで:
sudo -u postgres psql -c "CREATE DATABASE test_replication; \c test_replication; CREATE TABLE my_data (id SERIAL PRIMARY KEY, value TEXT, created_at TIMESTAMP DEFAULT NOW()); INSERT INTO my_data (value) VALUES ('Hello from Primary');"
Standbyサーバーで:
数秒後、Standbyでクエリを試行します(Standbyは読み取りのみを許可し、書き込みは許可しないことに注意してください):
sudo -u postgres psql -c "\c test_replication; SELECT * FROM my_data;"
StandbyにHello from Primaryが表示された場合、おめでとうございます、Streaming Replicationは正常に機能しています!
4.4. 基本的な監視
システムの長期的な安定性を確保するには、監視が不可欠です。次のことができます:
- PostgreSQLログの確認: PostgreSQLのログファイル(通常は
/var/log/postgresql/postgresql-14-main.log)には、レプリケーションの状態やエラーに関する貴重な情報が含まれています。 - 監視ツールの使用: 本番システムの場合、私は通常、PrometheusとGrafanaを統合して、
write_lag、replay_lag、ディスク容量、CPU、RAMなどのメトリックを監視します。これにより、潜在的な問題を早期に発見するのに役立ちます。
4.5. フェイルオーバーメカニズム
Streaming Replicationをセットアップしましたが、障害発生時のPrimaryからStandbyへの切り替え(フェイルオーバー)はこの構成では自動ではありません。これは手動プロセスです。自動化するには、Patroni、repmgr、pg_auto_failoverなどの専用クラスター管理ツールが必要になります。
Primaryサーバーに障害が発生した場合、Standbyを新しいPrimaryとしてアクティブ化するには、次のことが必要です:
- 古いPrimaryが完全に停止しているか、ネットワークから隔離されていることを確認します。
- Standbyサーバーで、
pg_ctl promoteコマンドを使用します。
sudo -u postgres pg_ctl -D /var/lib/postgresql/14/main promote
promote後、Standbyは新しいPrimaryとなり、書き込みクエリを受け入れ始めます。ただし、これは本番環境に適用する前に、ステージング環境で慎重に計画し、実践する必要があります。

