PostgreSQLクラスターのほぼゼロのダウンタイム自動アップグレードを実行するために開発したツール(pglupgrade)について書き始めました。この投稿では、ツールについて説明し、その設計の詳細について説明します。
シリーズの最初のパートは、クラウドでのPostgreSQLクラスターのほぼゼロのダウンタイム自動アップグレード(パートI)で確認できます。
ツールはAnsibleで書かれています。私は以前にAnsibleを使用した経験があり、現在は2ndQuadrantでも使用しています。そのため、Ansibleは快適なオプションでした。そうは言っても、お気に入りの自動化ツールを使用して、この投稿の後半で説明する最小限のダウンタイムアップグレードロジックを実装できます。
参考資料:ブログ投稿Ansible Loves PostgreSQL、PostgreSQL Planet in Ansible Galaxy、 プレゼンテーションAnsibleを使用したPostgreSQLの管理
Pglupgrade Playbook
Ansibleでは、プレイブック は、クラウドインスタンスのプロビジョニングやデータベースクラスターのアップグレードなどのプロセスを自動化するために開発されたメインスクリプトです。プレイブックには、1つ以上のプレイが含まれている場合があります 。プレイブックには変数が含まれている場合もあります 、役割 、およびハンドラー 定義されている場合。
このツールは、2つの主要なプレイブックで構成されています。最初のプレイブックはprovision.yml
です これは、仕様に従って、クラウドでLinuxマシンを作成するプロセスを自動化します(これは、クラウドインスタンスをプロビジョニングするためだけに作成され、アップグレードに直接関係しないオプションのプレイブックです )。 2番目の(そしてメインの)プレイブックはpglupgrade.yml
です。 データベースクラスターのアップグレードプロセスを自動化します。
Pglupgradeプレイブックには、アップグレードを調整するための8つのプレイがあります。各演劇では、1つの構成ファイルを使用します (config.yml
)、ホストインベントリファイルで定義されているホストまたはホストグループでいくつかのタスクを実行します (host.ini
。
インベントリファイル
インベントリファイルにより、Ansibleは、SSHを使用して接続する必要のあるサーバー、必要な接続情報、およびオプションでそれらのサーバーに関連付けられている変数を知ることができます。以下に、ツール用に設計されたケーススタディの1つで自動クラスターアップグレードを実行するために使用されたサンプルインベントリファイルを示します。これらのケーススタディについては、このシリーズの今後の投稿で説明します。
[old-primary] 54.171.211.188 [new-primary] 54.246.183.100 [old-standbys] 54.77.249.81 54.154.49.180 [new-standbys:children] old-standbys [pgbouncer] 54.154.49.180>
インベントリファイル(host.ini
)
サンプルインベントリファイルには、5つのホストが含まれています 5つのホストグループの下 old-primary
を含む 、new-primary
、old-standbys
、new-standbys
およびpgbouncer
。サーバーは複数のグループに属することができます。たとえば、old-standbys
new-standbys
を含むグループです グループ。これは、old-standbys
で定義されているホストを意味します。 グループ(54.77.249.81および54.154.49.180)もnew-standbys
に属しています グループ。つまり、new-standbys
グループはold-standbys
(の子)から継承されます グループ。これは、特別な:children
を使用して実現されます 接尾辞。
インベントリファイルの準備ができたら、AnsiblePlaybookはansible-playbook
を介して実行できます 以下に示すように、インベントリファイルをポイントしてコマンドを実行します(インベントリファイルがデフォルトの場所にない場合は、デフォルトのインベントリファイルを使用します)。
$ ansible-playbook -i hosts.ini pglupgrade.yml
Ansibleプレイブックの実行
構成ファイル
Pglupgrade Playbookは構成ファイル(config.yml
)を使用します )これにより、ユーザーは論理アップグレード変数の値を指定できます。
以下に示すように、config.yml
postgres_old_datadir
などのPostgreSQLクラスターのセットアップに必要なPostgreSQL固有の変数を主に格納します およびpostgres_new_datadir
新旧のPostgreSQLバージョンのPostgreSQLデータディレクトリのパスを保存します。 postgres_new_confdir
新しいPostgreSQLバージョンのPostgreSQL構成ディレクトリのパスを保存します。 postgres_old_dsn
およびpostgres_new_dsn
pglupgrade_user
の接続文字列を保存します pglupgrade_database
に接続できるようにする 新しいプライマリサーバーと古いプライマリサーバーの接続文字列自体は構成可能な変数で構成されているため、ユーザー(pglupgrade_user
)およびデータベース(pglupgrade_database
)さまざまなユースケースに合わせて情報を変更できます。
ansible_user: admin pglupgrade_user: pglupgrade pglupgrade_pass: pglupgrade123 pglupgrade_database: postgres replica_user: postgres replica_pass: "" pgbouncer_user: pgbouncer postgres_old_version: 9.5 postgres_new_version: 9.6 subscription_name: upgrade replication_set: upgrade initial_standbys: 1 postgres_old_dsn: "dbname={{pglupgrade_database}} host={{groups['old-primary'][0]}} user {{pglupgrade_user}}" postgres_new_dsn: "dbname={{pglupgrade_database}} host={{groups['new-primary'][0]}} user={{pglupgrade_user}}" postgres_old_datadir: "/var/lib/postgresql/{{postgres_old_version}}/main" postgres_new_datadir: "/var/lib/postgresql/{{postgres_new_version}}/main" postgres_new_confdir: "/etc/postgresql/{{postgres_new_version}}/main"
構成ファイル(config.yml
)
アップグレードの重要なステップとして、現在のバージョンのPostgreSQLバージョン情報を指定できます(postgres_old_version
)および(postgres_new_version
にアップグレードされるバージョン )。レプリケーションがバイト/ブロックレベルでのシステムのコピーである物理レプリケーションとは対照的に、論理レプリケーションでは選択的レプリケーションが可能です。 レプリケーションが論理データをコピーできる場所には、指定されたデータベースとそれらのデータベース内のテーブルが含まれます。このため、config.yml
pglupgrade_database
を介して複製するデータベースを構成できます 変数。また、論理レプリケーションユーザーにはレプリケーション権限が必要です。そのため、pglupgrade_user
変数は構成ファイルで指定する必要があります。 subscription_name
など、pglogicalの内部動作に関連する他の変数があります。 およびreplication_set
pglogicalの役割で使用されます。
Pglupgradeツールの高可用性設計
Pglupgradeツールは、さまざまなシステム要件に対応する高可用性(HA)プロパティの点で柔軟性をユーザーに提供するように設計されています。 initial_standbys
変数(config.yml
を参照) )は、アップグレード操作の実行中にクラスターのHAプロパティを指定するためのキーです。
たとえば、initial_standbys
は1に設定されます(クラスター容量が許す任意の数に設定できます)。これは、レプリケーションが開始する前に、アップグレードされたクラスターにマスターとともに1つのスタンバイが作成されることを意味します。つまり、4台のサーバーがあり、initial_standbysを1に設定すると、アップグレードされた新しいバージョンでは1台のプライマリサーバーと1台のスタンバイサーバーがあり、古いバージョンでは1台のプライマリサーバーと1台のスタンバイサーバーがあります。
このオプションを使用すると、アップグレードの実行中に既存のサーバーを再利用できます。 4台のサーバーの例では、レプリケーションの終了後に、古いプライマリサーバーとスタンバイサーバーを2台の新しいスタンバイサーバーとして再構築できます。
initial_standbys
の場合 変数が0に設定されている場合、レプリケーションが開始される前に、新しいクラスターに初期スタンバイサーバーが作成されることはありません。
initial_standbys
の場合 構成は紛らわしいように聞こえますが、心配しないでください。これについては、次のブログ投稿で2つの異なるケーススタディについて説明するときに詳しく説明します。
最後に、構成ファイルを使用すると、古いサーバーグループと新しいサーバーグループを指定できます。これは2つの方法で提供できます。まず、既存のクラスタがある場合、サーバーのIPアドレス(ベアメタルサーバーまたは仮想サーバーのいずれか )はhosts.ini
に入力する必要があります アップグレード操作中に必要なHAプロパティを考慮してファイルします。
2番目の方法は、provision.yml
を実行することです。 プレイブック(これがクラウドインスタンスのプロビジョニング方法ですが、独自のプロビジョニングスクリプトを使用することも、手動でインスタンスをプロビジョニングすることもできます )クラウド(AWS EC2インスタンス)で空のLinuxサーバーをプロビジョニングし、サーバーのIPアドレスをhosts.ini
に取得します ファイル。いずれにせよ、config.yml
hosts.ini
を介してホスト情報を取得します ファイル。
アップグレードプロセスのワークフロー
構成ファイル(config.yml
)pglupgradeプレイブックで使用されているので、アップグレードプロセスのワークフローを説明できます。
Pglupgradeワークフロー
上の図からわかるように、構成に基づいて最初に生成される6つのサーバーグループがあります(両方のhosts.ini
およびconfig.yml
)。 new-primary
およびold-primary
グループには常に1つのサーバーpgbouncer
があります グループには1つ以上のサーバーを含めることができ、すべてのスタンバイグループには0個以上のサーバーを含めることができます。実装に関しては、プロセス全体が8つのステップに分割されます。各ステップは、割り当てられたホストグループで必要なタスクを実行するpglupgradeプレイブックのプレイに対応しています。アップグレードプロセスは、次の演劇を通して説明されます:
- 構成に基づいてホストを構築します: 構成に基づいてサーバーの内部グループを構築する準備プレイ。このプレイの結果(
hosts.ini
と組み合わせて) コンテンツ)は、次の7つのプレイで使用される6つのサーバーグループ(ワークフロー図で異なる色で示されています)です。 - 初期スタンバイを使用して新しいクラスターをセットアップします: 新しいプライマリスタンバイと初期スタンバイ(定義されている場合)を使用して、空のPostgreSQLクラスターをセットアップします。これにより、以前の使用によるPostgreSQLインストールが残っていないことが保証されます。
- 論理レプリケーションをサポートするように古いプライマリを変更します: pglogical拡張機能をインストールします。次に、すべてのテーブルとシーケンスをレプリケーションに追加して、パブリッシャーを設定します。
- 新しいプライマリに返信します: 論理レプリケーションを開始するためのトリガーとして機能するサブスクライバーを新しいマスターにセットアップします。このプレイは、既存のデータの複製を終了し、複製を開始してから変更されたものに追いつき始めます。
- pgbouncer(およびアプリケーション)を新しいプライマリに切り替えます: レプリケーションラグがゼロに収束すると、pgbouncerを一時停止して、アプリケーションを徐々に切り替えます。次に、pgbouncer configを新しいプライマリにポイントし、レプリケーションの差がゼロになるまで待機します。最後に、pgbouncerが再開され、待機中のすべてのトランザクションが新しいプライマリに伝播され、そこで処理が開始されます。初期スタンバイはすでに使用されており、読み取り要求に応答します。
- 古いプライマリと新しいプライマリ間のレプリケーション設定をクリーンアップします: 古いプライマリサーバーと新しいプライマリサーバー間の接続を終了します。すべてのアプリケーションが新しいプライマリサーバーに移動され、アップグレードが実行されるため、論理レプリケーションは不要になります。プライマリサーバーとスタンバイサーバー間のレプリケーションは、物理レプリケーションで続行されます。
- 古いクラスターを停止します: 古いホストではPostgresサービスを停止して、アプリケーションがPostgresサービスに接続できないようにします。
- 新しいプライマリの残りのスタンバイを再構成します: 初期スタンバイ以外のホストが残っている場合は、他のスタンバイを再構築します。 2番目のケーススタディでは、再構築するスタンバイサーバーが残っていません。この手順により、hosts.iniのnew-standbysグループで指定されている場合、古いプライマリサーバーを新しいスタンバイとして再構築する機会が与えられます。既存のサーバー(古いプライマリでも)の再利用性は、pglupgradeツールの2段階のスタンバイ構成設計を使用して実現されます。ユーザーは、アップグレード前に新しいクラスターのスタンバイになるサーバーと、アップグレード後にスタンバイになるサーバーを指定できます。
結論
この投稿では、pglupgradeツールの実装の詳細と高可用性設計について説明しました。その際、ツールを例として使用して、Ansible開発のいくつかの重要な概念(つまり、プレイブック、インベントリ、および構成ファイル)についても説明しました。アップグレードプロセスのワークフローを説明し、各ステップが対応するプレイでどのように機能するかを要約しました。このシリーズの今後の投稿でケーススタディを示して、pglupgradeについて引き続き説明します。
読んでくれてありがとう!