PostgreSQLレプリケーションの習得:種類とセットアップの解説
高度なオープンソースリレーショナルデータベースの世界において、PostgreSQLはその堅牢性、拡張性、強力な機能で際立っています。中でも、データの冗長性と高可用性は、ミッションクリティカルなアプリケーションにとって極めて重要です。PostgreSQLレプリケーションは、1台のPostgreSQLサーバー(プライマリ)から1台以上の他のPostgreSQLサーバー(レプリカまたはスタンバイ)へデータをコピーすることで、これらの目標を達成するためのメカニズムです。
本記事では、PostgreSQLレプリケーションの核となる概念を探り、利用可能なさまざまな種類を調査し、それらをセットアップする方法に関する実践的なガイダンスを提供します。これらのメカニズムを理解することは、データが常時アクセス可能であり、ハードウェア障害から保護され、読み取り負荷の増加に対応できることを保証するために不可欠です。ストリーミングレプリケーションと論理レプリケーションの両方を取り上げ、それぞれのユースケース、利点、設定手順について説明します。
PostgreSQLレプリケーションが重要な理由
「どのように」に入る前に、「なぜ」を理解することが不可欠です。データの損失や長期にわたるダウンタイムは、ビジネスに深刻な影響を及ぼす可能性があります。レプリケーションは、以下の方法でこれらの懸念に対処します。
- 高可用性(HA): プライマリサーバーが障害を起こした場合、レプリカを迅速に昇格させて新しいプライマリにすることで、ダウンタイムを最小限に抑えることができます。
- 災害復旧(DR): レプリカを異なる地理的位置に配置することで、サイト固有の災害からデータを保護できます。
- 読み取りスケーラビリティ: 読み取り負荷の高いワークロードをレプリカにオフロードすることで、書き込み操作に専念するプライマリサーバーのパフォーマンスを向上させることができます。
- データ保護: レプリケーションは継続的なバックアップとして機能し、従来の定期的なバックアップよりも最新のデータコピーを提供します。
PostgreSQLは、レプリケーションのために主に2つの方法を提供します:ストリーミングレプリケーションと論理レプリケーション。どちらもデータ同期を達成しますが、異なる原則に基づいて動作し、異なるシナリオに適しています。
ストリーミングレプリケーション(物理レプリケーション)
ストリーミングレプリケーションは、PostgreSQLで最も一般的で基本的なレプリケーションの形態です。これは、Write-Ahead Log(WAL)レコードをプライマリサーバーから1台以上のレプリカに送信することによって機能します。これらのWALレコードは、データベースに加えられたすべての変更を表します。レプリカは、これらのWALレコードを自身のデータファイルに適用し、プライマリとの一貫性を保ちます。
ストリーミングレプリケーションの種類:
-
同期レプリケーション: 同期モードでは、プライマリサーバーは、トランザクションコミットをクライアントに確認応答する前に、少なくとも1つ(または指定された数)のレプリカからWALレコードが受信され、WALバッファに書き込まれたことの確認を待ちます。これにより、コミットされたトランザクションが少なくとも1つのレプリカに存在することが保証され、最高レベルのデータ一貫性が提供されます。
- 長所: 同期レプリカ上のコミット済みトランザクションのデータ損失を保証します。
- 短所: プライマリがレプリカの確認を待つ必要があるため、トランザクションコミットに遅延が発生する可能性があります。
-
非同期レプリケーション: 非同期モードでは、プライマリサーバーはWALレコードをレプリカに送信しますが、コミット確認を待たずにトランザクションをコミットします。プライマリはローカルにWALを書き込んだ後、直ちにクライアントにコミットを確認応答します。これにより遅延は少なくなりますが、WALレコードがレプリカに送信・適用される前にプライマリが障害を起こした場合、データ損失のリスクがあります。
- 長所: トランザクションコミット遅延への影響が最小限に抑えられます。
- 短所: プライマリが障害を起こし、WALレコードがまだレプリカに到達していない場合、データが失われる可能性があります。
ストリーミングレプリケーションの設定(非同期の例)
ストリーミングレプリケーションの設定には、プライマリサーバーとレプリカサーバーの両方の設定が必要です。以下に簡単な手順を示します。
1. プライマリサーバーの設定(postgresql.conf および pg_hba.conf)
プライマリサーバーでは、WALアーカイブとレプリケーション接続を有効にする必要があります。
-
postgresql.confの変更点:```ini
wal_level = replica # または論理レプリケーションの場合は logical
max_wal_senders = 5 # 同時レプリケーション接続数
wal_keep_size = 512MB # または古いバージョンでは wal_keep_segments同期レプリケーションの場合、以下を追加します:
synchronous_standby_names = 'replica1,replica2'
または特定のサーバー名/優先順位の場合:
synchronous_standby_names = '1 (replica1), 2 (replica2)'
archive_mode = on
archive_command = 'cp %p /path/to/wal_archive/%f'
`` *wal_level: ストリーミングレプリケーションには、少なくともreplicaである必要があります。 *max_wal_senders: 同時に接続できるスタンバイサーバーの数を指定します。 *wal_keep_size: レプリカが取得する前にWALファイルが削除されるのを防ぎます(基本的な設定ではarchive_commandの単純な代替ですが、堅牢性のためにアーカイブが推奨されます)。 *archive_mode&archive_command`: ポイントインタイムリカバリ(PITR)に不可欠であり、レプリカが遅延しすぎた場合や再構築が必要な場合に不可欠です。 -
pg_hba.confの変更点:レプリカがレプリケーションのために接続できるようにします。
replica_ip_addressをレプリカの実際のIPアドレスに置き換えてください。```ini
TYPE DATABASE USER ADDRESS METHOD
host replication replication_user replica_ip_address/32 md5
```レプリケーションユーザーを作成する必要もあります。
sql -- プライマリサーバーで: CREATE ROLE replication_user WITH REPLICATION LOGIN PASSWORD 'your_password';これらのファイルを変更した後、PostgreSQLの設定をリロードします。
```bash
pg_ctl reload必要に応じてPostgreSQLを再起動
```
2. レプリカサーバーの準備
レプリカを起動する前に、プライマリのデータディレクトリの特定の時点のコピーであるデータディレクトリを持っている必要があります。最も簡単な方法はpg_basebackupを使用することです。
-
レプリカ上のPostgreSQLを停止します(実行中の場合)。
-
ベースバックアップの取得:
```bash
PGDATAが空であることを確認するか、最初に削除します
pg_basebackup -h primary_host_ip -p 5432 -U replication_user -D /var/lib/postgresql/data/ -Fp -Xs -P
`` *-h,-p,-U: プライマリサーバーの接続詳細を指定します。 *-D: レプリカのデータディレクトリです。 *-Fp: フォーマットはプレーンです。 *-Xs: ストリームTSL/WALストリーミングを使用します。WALストリーミングを設定するprimary_conninfo設定と同等です。 *-P: 進捗を表示します。 *replication_user`のパスワードを求められます。
3. レプリカサーバーの設定(postgresql.conf および PG12以降ではrecovery.confまたはpostgresql.conf)
-
postgresql.confの変更点(PG12以降):```ini
hot_standby = on # レプリカでの読み取り専用クエリを許可します
primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'同期レプリケーションの場合、以下を追加します:
primary_promote_delay = 10 # 秒
またはトリガーファイル機構を使用します
`` *hot_standby: スタンバイでの読み取り専用クエリを有効にします。 *primary_conninfo`: プライマリサーバーへの接続文字列です。 -
recovery.conf(PostgreSQLバージョン12より前):レプリカのデータディレクトリに以下の内容の
recovery.confファイルを作成します。```ini
standby_mode = 'on'
primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'ストリーミングの代わりにアーカイブリカバリを使用する場合、restore_commandを指定します
restore_command = 'cp /path/to/wal_archive/%f %p'
recovery_target_timeline = 'latest'
```
PG12以降では、
primary_conninfoとhot_standbyはpostgresql.confに直接設定されます。
4. レプリカサーバーの起動
レプリカでPostgreSQLサービスを起動します。プライマリに接続し、WALレコードを受信し、同期を開始します。ログで確認できます。
ヒント: 堅牢なHAのためには、フェイルオーバーと管理を自動化するPatroniやrepmgrなどのツールを検討してください。
論理レプリケーション
論理レプリケーションは、PostgreSQL 10で導入された、より柔軟で粒度の高いレプリケーションの形態です。データブロック全体やWALレコードを複製する代わりに、行レベルでデータ変更をその論理的な意味(例:INSERT、UPDATE、DELETEステートメント)に基づいて複製します。これは、WALレコードを論理的な変更のストリームにデコードすることによって実現されます。
主な機能とユースケース:
- 選択的なレプリケーション: 複製するテーブルや列を選択できます。これは、データベース間でデータを選択的に移動する場合に非常に役立ちます。
- クロスバージョンレプリケーション: 論理レプリケーションは、異なるメジャーバージョンのPostgreSQL間でデータを複製できます。
- 選択的なスキーマ変更: 特定のデータベースやスキーマの変更を複製でき、特定のテーブルのみを公開することもできます。
- データ変換: 内蔵されてはいませんが、論理レプリケーションはより複雑なETL(抽出、変換、ロード)プロセスの基盤を提供します。
- 完全なクローンではないレプリカへのプライマリからのレプリケーション: ターゲットデータベースはソースの完全な物理コピーである必要はありません。
仕組み:
- パブリッシャー: データ変更が発生するソースデータベース(プライマリ)。
wal_level = logicalが必要です。変更はWALから論理ストリームにデコードされます。 - パブリケーション: パブリッシャー上にある、複製されるテーブルのセットを名前付けたものです。
- サブスクライバー: 変更を受信するターゲットデータベース(レプリカ)。
- サブスクリプション: サブスクライバー上にある接続で、パブリッシャーに接続し、特定のパブリケーションからの変更を適用します。
論理レプリケーションの設定
1. パブリッシャー(プライマリサーバー)の設定
-
postgresql.confの変更点:ini wal_level = logical max_replication_slots = 10 # 論理レプリケーションスロット用 max_wal_senders = 10 # max_replication_slots以上である必要があります -
パブリケーションの作成:
```sql
-- パブリッシャーのデータベースで:
CREATE PUBLICATION my_publication FOR TABLE
table1,
table2
WITH (publish = 'insert,update,delete');-- 全てのテーブルの場合:
-- CREATE PUBLICATION all_tables_pub FOR ALL TABLES;
```パブリッシャーの設定をリロードします。
2. サブスクライバー(レプリカサーバー)の設定
-
ターゲットテーブルの存在確認: サブスクライバーデータベースには、パブリッシャーと同じスキーマを持つターゲットテーブルが存在する必要があります。手動で作成するか、
pg_dumpを使用してスキーマを抽出できます。 -
サブスクリプションの作成:
sql -- サブスクライバーのデータベースで: CREATE SUBSCRIPTION my_subscription CONNECTION 'host=publisher_host_ip port=5432 user=replication_user password=your_password dbname=publisher_db' PUBLICATION my_publication;replication_userはパブリッシャーに対して適切な権限を持っている必要があります。PostgreSQLはパブリッシャー上にレプリケーションスロットを自動的に作成し、変更の適用を開始します。
pg_stat_subscriptionを使用してサブスクリプションのステータスを監視できます。
ヒント: 論理レプリケーションにはlogical decoding拡張機能が必要ですが、通常は組み込まれています。ストリーミングレプリケーションよりもリソースを多く消費しますが、より大きな柔軟性を提供します。
適切なレプリケーション方法の選択
- ストリーミングレプリケーション: 高可用性および災害復旧に最適です。プライマリのバイト単位の正確なコピーが必要な場合に使用します。完全なデータベースレプリケーションのためにセットアップがより簡単で、読み取り専用レプリカに対して最高の読み取りスケーラビリティを提供します。
- 論理レプリケーション: 選択的なデータ配布、移行、クロスバージョンアップグレード、またはデータの一部のみを複製する必要がある場合に最適です。異なるスキーマへの複製やデータ変換など、より複雑なシナリオを可能にします。
結論
PostgreSQLレプリケーションは、堅牢なデータ可用性、リカバリ、スケーラビリティを可能にする強力な機能です。包括的なデータミラーリングを提供するストリーミングレプリケーションを選択するか、柔軟で選択的なアプローチである論理レプリケーションを選択するかにかかわらず、それらのメカニズムと設定を理解することが、健全で回復力のあるPostgreSQL環境を維持するための鍵となります。レプリケーションを実装することにより、データベースの耐障害性とパフォーマンス機能を大幅に向上させることができます。
必ずレプリケーション設定全体をテストしてください(特にフェイルオーバーシナリオ)し、レプリカが最新の状態であることを確認するためにレプリケーションの遅延を監視してください。PostgreSQLの進化する機能に対する継続的な学習と適応は、この不可欠なデータベースシステムの習熟度をさらに固めるでしょう。