ノート:
- このチュートリアルではOracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントの値の例を使用します。演習を完了するときは、これらの値をクラウド環境に固有の値に置き換えます。
可用性の高いPostgresクラスタをOracle Cloud Infrastructureにデプロイ
イントロダクション
このチュートリアルでは、Patroniおよびその他のコンポーネントを使用したHA構成でのPostgresの設計および実装の概要を示します。PostgreSQLには、障害が発生したマスターをクラスタに追加するための組込みの自動フェイルオーバーおよび自動メカニズムがありません。Patroniは、クラウドネイティブ機能とフェイルオーバー/スイッチオーバーおよび自動ブートストラップおよびレプリカの設定のための高度なオプションを備えた、PostgreSQLの時代の高可用性(HA)ソリューションです。
Patroniは、Pythonを使用して独自のカスタマイズされたHAソリューションを作成し、アクセス性を最大限に高めるためのテンプレートで、etcdなどの分散構成ストアを作成します。
次に、PatroniのネイティブPostgresレプリケーションとそのソリューションに関するいくつかの制限事項を示します。
ネイティブのPostgresレプリケーションの制限 | パトロニベースのソリューション |
---|---|
デフォルトのレプリケーションメカニズムでは、自動フェイルオーバーはサポートされません。 | Patroniは自動フェイルオーバーを提供します。 |
外部ツールをフェイルオーバーに使用すると、それらを起動して実行し続けるために追加の作業が必要になる場合があります。 | パトロニはフェイルオーバーを処理します。 |
Postgresのモニタリングも課題です。 | Patroniには、Postgresサービスを監視する組込みメカニズムがあります。 |
障害が発生したノードをクラスタに自動的に追加するには、高度なスクリプト・スキルが必要です。 | Patroniには、障害が発生したノードをクラスタに戻すための自動化が組み込まれています。 |
スプリット・ブレインのシナリオを処理できません。 | ETCDの助けを借りたパトロニは、新しいリーダーを選ぶことができるだろう。 |
その他のPostgreSQL HAソリューションには次のものがあります。
- 肩書き
- PostgreSQL自動フェイルオーバー(PAF)
- PGルックアウト
- pgPool- II
ただし、PatroniをPostgres実装とともに使用すると、クラスタ管理のライフサイクル全体が大幅に簡略化されます。
-
ETCDは分散構成ストア(DCS)として使用されます。PostgreSQLクラスタの状態が格納されます。PostgreSQLノードの状態が変更されると、PatroniはETCDキー/値ストアの状態変更を更新します。ETCDでは、この情報を使用してマスター ノードを選択し、クラスタを稼働させ続けます。
-
pgBackrestは、自動バックアップのためのシンプルで信頼性の高いソリューションです。Pgbackrestの利点:
- これは物理バックアップ・ツールであり、差分バックアップ、増分バックアップおよび完全バックアップを実行できます。
- パラレル・ジョブを構成してバックアップを実行できます。
- スタンバイ・サーバーからバックアップを取得できます。
- 非同期WAL(書込み先アーカイブ・ログ)のプッシュとプル
- 複数のリポジトリを構成できます。
- OCI/GCP/S3/Azureへのクラウド・バックアップ・オプション
-
OCI Network Load Balancerは、HAProxyではなくリーダー・ノードと通信するために使用されます。管理対象サービスであるOracle Cloud Infrastructure (OCI) Network Load Balancerは、この設定と簡単に統合できます。
目標
このチュートリアルでは、Postgresデータベースを(AWSまたは他のクラウド・ベンダーから)OCIに移行する可能性のある代替手段を備えた、実行可能な高パフォーマンス・ソリューションをリストします。HAおよびリアルタイムのデータ移行の主な要件。
アーキテクチャ
次のアーキテクチャは、3つのETCDサーバー、3つの(Postgres + Patroni + Pgbackrest)サーバー、Object StorageバケットおよびNetwork Load Balancerで構成されます。
推奨
- HA: 3つのETCDサーバーを使用し、PostgreSQLには3つのノードを使用し、異なるアベイラビリティ・ドメインに配置します。
- スループットを向上させるには、データ、一時、ウォルおよびログ・ファイル用に個別のブロック・ボリュームを作成します。
- クラスタ作成時の
patroni.yaml
ブートストラップ・セクションで、すべてのカスタム・パラメータを定義します。
PostgreSQL HAコンポーネントの構成およびインストール
設定は次の2つの部分に分かれています。
- インフラストラクチャのプロビジョニング
- ソフトウェアのインストールと構成
タスク1: インフラストラクチャのプロビジョニング
-
コンピュートVMの作成:
- 3つのETCDサーバー
- Postgres + Patroni用の3台のサーバー(1人のリーダーと2つのレプリカ)
-
バックアップを格納するためのオブジェクト・ストレージ・バケットを作成します。
-
前述のオブジェクト・ストア・バケットに対するREAD/WRITEアクセス権を持つOCIテナンシ・ユーザーを作成します。
タスク2: ソフトウェアのインストールおよび構成
-
ETCDを設定します。
-
3台のサーバーにETCDをインストールします。
cd /tmp wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz tar xzvf /tmp/etcd-v3.5.2-linux-amd64.tar.gz cd etcd-v3.5.2-linux-amd64 cp etcdutl etcdctl etcd /usr/local/bin/ mkdir -p /etc/etcd mkdir -p /var/lib/etcd groupadd -f -g 1501 etcd useradd -c "etcd user" -d /var/lib/etcd -s /bin/false -g etcd -u 1501 etcd chown -R etcd:etcd /var/lib/etcd
-
3台すべてのサーバーでETCDを設定および起動します。
以下は、ETCDサーバーの詳細です。
| Hostname | IP Address | Availability Domain | | --- | --- | --- | | pg-etcd-01 | 192.0.2.4 | AD1 | | pg-etcd-02 | 192.0.2.5 | AD2 | | pg-etcd-03 | 192.0.2.6 | AD3 |
ノート: 要件に従ってIPを変更します。
pg- etcd-01
vi /etc/etcd/etcd.conf ###Node1 ##192.0.2.4 ETCD_NAME="pg-etcd-01" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.4:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.4:2379" ETCD_LISTEN_PEER_URLS="http://192.0.2.4:2380,http://127.0.0.1:7001" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.4:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
pg- etcd-02
vi /etc/etcd/etcd.conf ##Node2 ##192.0.2.5 ETCD_NAME=" pg-etcd-02" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.5:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.5:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.5:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.5:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
pg- etcd-03
vi /etc/etcd/etcd.conf ##Node3 ##192.0.2.6 ETCD_NAME="pg-etcd-03" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380,pg-etcd-03=http://192.0.2.6:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.6:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.6:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.6:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.6:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
-
pg- etcd-01にメンバーを追加します。
etcdctl member add pg-etcd-02 --peer-urls=http://192.0.2.5:2380 etcdctl member add pg-etcd-03 --peer-urls=http://192.0.2.6:2380
-
次のコマンドを実行して、メンバー・リストを表示します。
etcdctl member list
-
サービスを作成します。
vi /etc/systemd/system/etcd.service [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify WorkingDirectory=/var/lib/etcd EnvironmentFile=-/etc/etcd/etcd.conf User=etcd # set GOMAXPROCS to number of processors ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd" Restart=on-failure LimitNOFILE=65536 IOSchedulingClass=best-effort IOSchedulingPriority=0 [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl enable etcd
-
-
Postgresをすべてのノードにインストールします。次のスクリプトを実行してPostgresをインストールします。
-
ノート: Replicaの場合、postgresqlを停止し、Patroni構成が完了するとリーダーからコピーされるため、データ・ディレクトリを削除します。
/opt/pgsql/bin/pg_ctl -D /opt/pgsql/data/$MAJORVERSION stop cd /opt/pgsql/data/ rm *
-
-
拡張機能をインストール: pg_squeezeおよびpgaudit。
-
PGAUDITのインストール
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/pgaudit/pgaudit/archive/refs/heads/REL_12_STABLE.zip unzip REL_12_STABLE.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
PG_SQUEEZEのインストール
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/cybertec-postgresql/pg_squeeze/archive/refs/heads/master.zip unzip master.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
-
すべてのノードにPatroniをインストールします。
yum update –y yum -y install epel-release yum -y install python3 yum install -y python3-devel yum install -y psutils yum install -y gcc yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install python3-psycopg2 pip3 install python-etcd pip3 install patroni
-
すべてのノードにpgBackrestをインストールして構成します。
-
Pgbackrestのインストール
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install pgbackrest -y
-
すべてのノードでPgbackrestを構成します
/etc/pgbackrest.conf [global] repo1-type=s3 repo1-path=/backup repo1-s3-uri-style=path repo1-s3-region=us-ashburn-1 repo1-s3-endpoint=https://xxxxx0011.compat.objectstorage.us-ashburn-1.oraclecloud.com repo1-s3-key=0000000a90d57eddexxxxxa3dc7c4f700000ed2e6 repo1-s3-key-secret=1UhXj69xxxx1e6OyF+00000cccccyyyuuu= repo1-s3-bucket=pg_backup repo1-retention-full=10 log-level-console=info log-level-file=debug log-path=/var/log/pgbackrest/ [stanza-name] pg1-path=/opt/pgsql/data pg1-user=Postgres
-
すべてのノードでブートストラップ・ファイルを作成します。
vi /etc/patroni/boot_pgbackrest.sh #!/ usr / bin /env bash while getopts ": -:" optchar ; do [[ "${ optchar }" == "-" ]] || continue case "${ OPTARG }" in datadir =* ) DATA_DIR =${ OPTARG #*=} ;; scope =* ) SCOPE =${ OPTARG #*=} ;; esac done /bin/pgbackrest --stanza=$SCOPE --link-all restore
-
-
すべてのノードでPatroniを構成します。
ホスト名 IPアドレス 可用性ドメイン pg- db-01 192.0.2.1 AD1 pg- db-02 192.0.2.2 AD2 pg- db-03 192.0.2.3 AD3 ノート: 要件に従ってIPを変更します。
mkdir -p /etc/patroni mkdir -p /opt/pgsql/patroni chown postgres:postgres -R /opt/pgsql/patroni chmod 700 /opt/pgsql/patroni vi /etc/patroni/patroni.yml scope:pg-ha-cluster name:pg-db-01 namespace:/opt/pgsql/patroni/ ### restapi: listen: "192.0.2.1:8008" connect_address: "192.0.2.1:8008" ###ETCD Configuration etcd: hosts: "192.0.2.4:2379,192.0.2.5:2379, 192.0.2.6:2379" ###Bootstrap bootstrap: dcs: ttl: 120 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters: archive_command: "pgbackrest --stanza=<stanza-name> archive-push %p" archive_mode: on archive_timeout: 900s log_file_mode: "0640" log_filename: postgresql-%u.log log_rotation_age: 1d log_truncate_on_rotation: "on" logging_collector: "on" max_connections: 2000 max_replication_slots: 10 max_wal_senders: 10 max_wal_size: 5GB max_worker_processes: 40 min_wal_size: 1GB wal_level: "replica" password_encryption: scram-sha-256 superuser_reserved_connections: 200 create_replica_methods: - pgbackrest pgbackrest: command: "/usr/bin/pgbackrest --stanza=<stanza-name> restore --delta --link-all" keep_data: True no_params: True recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' method: pgbackrest pgbackrest: command: /etc/patroni/boot_pgbackrest.sh keep_existing_recovery_conf: False recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 192.0.2.1/32 md5 - host replication replicator 192.0.2.2/32 md5 - host replication replicator 192.0.2.3/32 md5 - host all all x.x.x.0/0 md5 users: admin: password: admin options: - createrole - createdb #####Local Postgresql Parameters postgresql: listen: "192.0.2.1:5432" connect_address: "192.0.2.1:5432" data_dir: /opt/pgsql/data pgpass: /opt/pgsql/patroni/pgpass authentication: replication: username: replicator password: password superuser: username: postgres password: password # rewind: # username: replicator # password: password parameters: unix_socket_directories: "/var/run/postgresql, /tmp" ###Any Tags tags: nofailover: false noloadbalance: false clonefrom: false nosync: false
ノート: 各ノードのIPをそれぞれ変更します。
chmod 640 /etc/patroni/patroni.yml chown postgres:postgres -R /etc/patroni/patroni.yml
- すべてのノードでPatroniサービスを作成
vi /etc/systemd/system/patroni.service [Unit] Description=Runners to orchestrate a high-availability PostgreSQL - patroni After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=~ # Where to send early-startup messages from the server # This is normally controlled by the global default set by systemd # StandardOutput=syslog
# Pre-commands to start watchdog device # Uncomment if watchdog is part of your patroni setup #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog # Start the patroni process ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml # Send HUP to reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # Only kill the patroni process, not its children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=60 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable patroni sudo systemctl start patroni sudo systemctl status patroni
ノート: Replicaノードで、Patroniを構成しますが、サービスは起動しません。
-
次のコマンドを実行して、マスター上のPatroniクラスタ・ステータスを確認します。
patronictl -c /etc/patroni/patroni.yml list [root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 1 | | +--------------+-------------+---------+---------+----+-----------+
-
Stanzaを作成し、完全バックアップを実行します。
pgbackrest --stanza=<stanza-name> stanza-create pgbackrest --type=full --stanza= pgha --process-max=10 backup pgbackrest info
-
ReplicaノードでPatroniを起動し、リーダーから自動的にキャッチアップを開始します。
sudo systemctl start patroni sudo systemctl status patroni
- 次のコマンドを実行して、クラスタのステータスを確認します。
patronictl -c /etc/patroni/patroni.yml list
ステータスは次のとおりです:
[root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 2 | | | pg-db-02 | 192.0.2.2 | Replica | running |2 | 0 | | pg-db-03 | 192.0.2.3 | Replica | running | 2 | 0 | +--------------+-------------+---------+---------+----+-----------+
-
最後に、ログ・クリーンアップ、バックアップなどのcronジョブを設定します。
crontab –e #Pgbackrest FULL Backup on Sunday @1AM 00 01 * * 0 postgres pgbackrest --type=full --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Pgbackrest INC Backup on Mon-Sat @1AM 00 01 * * 1-6 postgres pgbackrest --type=diff --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Delete PostgreSQL logs 08 * * * find /opt/pgsql/log/* -mtime +15 -exec rm {} \; &>/dev/null
その他のPatroniコマンド
-
メンバーのリスト
patronictl -c /etc/patroni/patroni.yml list
-
フェイルオーバー/再起動/スイッチオーバー
patronictl -c /etc/patroni/patroni.yml failover patronictl -c /etc/patroni/patroni.yml restart patronictl -c /etc/patroni/patroni.yml switchover
-
パラメータの更新
patronictl -c /etc/patroni/patroni.yml edit-config -p log_directory='/opt/pgsql/log/' patronictl -c /etc/patroni/patroni.yml show-config
-
再読み込み
patronictl -c /etc/patroni/patroni.yml reload <cluster_name>
関連リンク
- Linuxインスタンスの作成方法
- オブジェクト・ストレージ・バケットの概要
- IAMユーザーの作成
- ネットワークLoad Balancerの作成方法
- 顧客キーの操作
- PostgreSQLダウンロード
- PostgresSQLインストール
- パトロニ
- Etcdのインストール
確認
- 著者: Deepika Nayak、Shreyas Rane、Divya Das
その他の学習リソース
他のラボをdocs.oracle.com/learnで探すか、Oracle LearningのYouTubeチャネルでより無料の学習コンテンツにアクセスします。また、education.oracle.com/learning-explorerにアクセスしてOracle Learningエクスプローラになります。
製品のドキュメントは、Oracle Help Centerを参照してください。
Deploy a highly available Postgres cluster on Oracle Cloud Infrastructure
F74179-01
November 2022
Copyright © 2022, Oracle and/or its affiliates.