sql >> データベース >  >> RDS >> PostgreSQL

論理レプリケーションを使用したPostgreSQL11へのアップグレード

    時間です。

    約1年前に、ネイティブ論理レプリケーションをサポートするPostgreSQL10を公開しました。論理レプリケーションの用途の1つは、PostgreSQLのメジャーバージョン間でダウンタイムを低くまたはまったくアップグレードできないようにすることです。これまで、PostgreSQL 10はネイティブ論理レプリケーションを備えた唯一のPostgreSQLリリースであったため、この方法でアップグレードする機会はあまりありませんでした。 (論理レプリケーションは、異なるオペレーティングシステムやCPUアーキテクチャ上のインスタンス間で、またはブロックサイズやロケールなどの異なる低レベルの構成設定でデータを移動するためにも使用できます。必要に応じてサイドグレードします。)PostgreSQL 11が近づいたので、次のようになります。この機能を利用するその他の理由。

    まず、PostgreSQLインストールをアップグレードする3つの主な方法を比較してみましょう。

    • pg_dumpと復元
    • pg_upgrade
    • 論理レプリケーション

    これらの方法を、堅牢性、速度、必要なダウンタイム、および制限の観点から比較できます(さらに、この記事ではどこかで停止する必要があります)。

    pg_dumpとrestoreは、最もテストされており、何十年も使用されているため、間違いなく最も堅牢な方法です。また、処理できる内容に関する制限もほとんどありません。ダンプおよび復元できないデータベースを構築することは可能ですが、ほとんどの場合、特定のオブジェクトの依存関係が関係していますが、それらはまれであり、通常は推奨されない方法が含まれます。

    もちろん、ダンプと復元の方法の問題は、ダンプと復元の操作が実行されている間、実質的にダウンタイムが必要になることです。プロセスの実行中もソースデータベースの読み取りと書き込みは可能ですが、ダンプの開始後のソースデータベースへの更新はすべて失われます。

    pg_upgradeは、データファイルを論理テキスト形式にダンプすることなく直接移動することにより、pg_dumpプロセスを改善します。 pg_upgradeは引き続き内部でpg_dumpを使用してスキーマをコピーしますが、データは使用しないことに注意してください。 pg_upgradeが新しくなったとき、その堅牢性が疑問視され、一部のデータベースが誤ってアップグレードされました。しかし、pg_upgradeは現在かなり成熟しており、十分にテストされているため、その理由でそれを使用することを躊躇する必要はありません。 pg_upgradeの実行中、データベースシステムはダウンしています。ただし、pg_upgradeの実行時間については選択できます。デフォルトのコピーモードでは、合計実行時間は、スキーマのダンプと復元にかか​​る時間(数千のテーブルやその他のオブジェクトがない限り、通常は非常に高速です)と、データファイルをコピーする時間で構成されます。データベースの大きさ(およびI / Oシステム、ファイルシステムなど)。

    オプションのリンクモードでは、データファイルは代わりに新しいデータディレクトリにハードリンクされるため、時間はすべてのバイトをコピーするのではなく、ファイルごとに短いカーネル操作を実行する時間にすぎません。欠点は、アップグレードで問題が発生した場合、または古いインストールにフォールバックする必要がある場合、この操作によって古いデータベースが破壊されることです。 (サポートされているファイルシステムでreflinksまたはファイルクローン操作を使用して、PostgreSQL 12の両方の世界で最高のソリューションに取り組んでいます。)

    論理レプリケーションはここで最も新しいものであるため、ねじれを解決するにはおそらく時間がかかります。調査して調査する時間がない場合は、これが現時点での方法ではない可能性があります。 (もちろん、人々はPostgreSQLをアップグレードするために、Slony、Londiste、pglogicalなどの他の非コア論理レプリケーションソリューションを長年使用しているため、詳細ではないにしても、原則について多くの経験があります。)

    論理レプリケーションを使用してアップグレードすることの利点は、データの同期が行われている間、アプリケーションが古いインスタンスに対して実行を継続できることです。クライアント接続が切り替えられている間は、わずかな停止が必要です。したがって、論理レプリケーションを使用したアップグレードは、コピーモードでpg_upgradeを使用するよりも開始から終了までの時間が遅くなりますが(ハードリンクモードを使用するよりも確実に遅くなります)、実際のダウンタイムははるかに短くなる可能性があるため、それほど重要ではありません。

    現在、論理レプリケーションはスキーマの変更をレプリケートしないことに注意してください。この提案されたアップグレード手順では、スキーマは引き続きpg_dumpを介してコピーされますが、その後のスキーマ変更は引き継がれません。論理レプリケーションを使用したアップグレードには、他にもいくつかの制限があります。大きなオブジェクト、TRUNCATE、シーケンスの変更など、特定の操作は論理レプリケーションによってキャプチャされません。これらの問題の回避策については後で説明します。

    物理的なスタンバイがある場合(そうでない場合は、なぜそうしませんか?)、メソッド間で考慮すべきいくつかの違いもあります。どちらの方法でも、アップグレードされたインスタンスの新しい物理スタンバイを構築する必要があります。ダンプと復元、および論理レプリケーションを使用すると、アップグレードを開始する前にそれらを配置できるため、復元または論理レプリケーションの初期同期が完了すると、レプリケーションの遅延が発生する可能性があり、スタンバイの準備がほぼ整います。

    pg_upgradeでは、プライマリのアップグレードが完了した後に新しいスタンバイを作成する必要があります。 (pg_upgradeのドキュメントでは、これについてさらに詳しく説明しています。)高可用性をフィジカルスタンバイに依存している場合は、新しいインスタンスに切り替える前にスタンバイを配置する必要があるため、スタンバイのセットアップが全体的なタイミング計算に影響を与える可能性があります。

    しかし、論理レプリケーションに戻ります。論理レプリケーションを使用したアップグレードの方法は次のとおりです。

    0.古いインスタンスは論理レプリケーション用に準備する必要があります。これには、http://www.postgresql.org/docs/10/static/logical-replication-config.html(主にwal_level = logical)で説明されているいくつかの構成設定が必要です。 。これらの変更を行う必要があることが判明した場合は、サーバーを再起動する必要があります。したがって、これを事前によく確認してください。 pg_hba.confも確認してください 古いインスタンスでは、新しいインスタンスからの接続を受け入れるように設定されています。 (リロードのみが必要な変更。)

    1.新しいPostgreSQLバージョンをインストールします。少なくとも、pg_dumpを含むサーバーパッケージとクライアントパッケージが必要です。現在、多くのパッケージで複数のバージョンを並べてインストールできます。仮想マシンまたはクラウドインスタンスを実行している場合は、新しいインスタンスを新しいホストにインストールすることを検討する価値があります。

    2.新しいインスタンスを設定します。つまり、initdbを実行します。新しいインスタンスは、ロケール、WALセグメントサイズ、チェックサムなど、古いインスタンスとは異なる設定を持つことができます。 (この機会を利用してデータチェックサムをオンにしてみませんか?)

    3.新しいインスタンスを開始する前に、いくつかの構成設定を変更する必要がある場合があります。インスタンスが古いインスタンスと同じホストで実行されている場合は、別のポート番号を設定する必要があります。また、postgresql.confで行ったカスタム変更を引き継ぎます メモリ設定などの古いインスタンスでは、max_connections 、など。同様に、pg_hba.confを作成します。 ご使用の環境に適した設定。通常、pg_hba.confをコピーすることから始めることができます 古いインスタンスからのファイル。 SSLを使用する場合は、今すぐ設定してください。

    4.新しい(空の)インスタンスを開始し、満足のいくように機能することを確認します。新しいホストに新しいインスタンスを設定する場合は、この時点で、新しいホストから古いデータベースインスタンスへのデータベース接続(psqlを使用)が可能であることを確認してください。後続のステップでそれが必要になります。

    5.pg_dumpallを使用してスキーマ定義をコピーします。 (または、データベースごとにpg_dumpを使用して個別に実行できますが、ロールなどのグローバルオブジェクトを忘れないでください。)

    pg_dumpall -s >schemadump.sql
    psql -d postgres -f schemadump.sql

    この時点以降のスキーマ変更は移行されません。それらを自分で管理する必要があります。多くの場合、変更するDDLを両方のホストに適用するだけで済みますが、アップグレード中にテーブル構造を変更するコマンドを実行することは、おそらくやりすぎです。

    6.ソースインスタンスの各データベースで、すべてのテーブルをキャプチャするパブリケーションを作成します。

    CREATE PUBLICATION p_upgrade FOR ALL TABLES;

    論理レプリケーションは各データベースで個別に機能するため、これを各データベースで繰り返す必要があります。一方、すべてのデータベースを一度にアップグレードする必要はないため、一度に1つのデータベースをアップグレードすることも、一部のデータベースをアップグレードしないこともできます。

    7.ターゲットインスタンスの各データベースで、作成したばかりのパブリケーションをサブスクライブするサブスクリプションを作成します。ソースデータベースとターゲットデータベースを正しく一致させてください。

    CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

    必要に応じて接続パラメータを設定します。

    8.ここで、サブスクリプションが初期データをコピーし、パブリッシャーに完全に追いつくまで待ちます。システムカタログpg_subscription_relで、サブスクリプション内の各テーブルの初期同期ステータスを確認できます。 (rを探します =列srsubstateで準備完了 )。レプリケーションの全体的なステータスは、pg_stat_replicationで確認できます。 送信側とpg_stat_subscription 受信側で。

    9.上記のように、シーケンスの変更は複製されません。これに対する考えられる回避策の1つは、pg_dumpを使用してシーケンス値をコピーすることです。次のようなものを使用して、現在のシーケンス値のダンプを取得できます。

    pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

    (これは、シーケンス名がすべて*_seqと一致することを前提としています。 その名前に一致するテーブルはありません。より複雑なケースでは、完全なダンプを作成し、ダンプの目次からシーケンスデータを追加するルートをたどることもできます。)

    これを行うとシーケンスが進む可能性があるため、おそらくseq-data.sqlを変更してください。 数字に少したるみを加えるためのファイル。

    次に、psqlを使用してそのファイルを新しいデータベースに復元します。

    10. Showtime:アプリケーションを新しいインスタンスに切り替えます。これには、事前に考える必要があります。最も単純なシナリオでは、アプリケーションプログラムを停止し、接続設定を変更して、再起動します。接続プロキシを使用する場合は、そこで接続を切り替えることができます。また、クライアントアプリケーションを1つずつ切り替えて、少しテストしたり、新しいシステムの負荷を軽減したりすることもできます。これは、古いサーバーを指しているアプリケーションと新しいサーバーを指しているアプリケーションが競合する書き込みを行わない限り、機能します。 (その場合、少なくとも短時間はマルチマスターシステムを実行することになりますが、これはもう1つの複雑さです。)

    11.アップグレードが完了したら、レプリケーション設定を破棄できます。新しいインスタンスの各データベースで、

    を実行します。
    DROP SUBSCRIPTION s_upgrade;

    古いインスタンスをすでにシャットダウンしている場合は、リモートサーバーに到達してレプリケーションスロットを削除できないため、これは失敗します。この状況で続行する方法については、DROPSUBSCRIPTIONのマニュアルページを参照してください。

    パブリケーションをソースインスタンスにドロップすることもできますが、パブリケーションはリソースを保持しないため、これは必要ありません。

    12.最後に、古いインスタンスが不要になった場合は削除します。

    論理レプリケーションでサポートされていないものの回避策に関する追加のコメント。大きなオブジェクトを使用している場合は、もちろん、アップグレードプロセス中に変更されない限り、pg_dumpを使用してオブジェクトを移動できます。これは重大な制限であるため、大きなオブジェクトを頻繁に使用する場合は、この方法が適切でない可能性があります。アップグレードプロセス中にアプリケーションがTRUNCATEを発行した場合、それらのアクションは複製されません。おそらく、アプリケーションを微調整して、アップグレード時にそれが行われないようにするか、代わりにDELETEに置き換えることができます。 PostgreSQL 11はTRUNCATEの複製をサポートしますが、これはソースインスタンスと宛先インスタンスの両方がPostgreSQL11以降である場合にのみ機能します。

    すべてのアップグレード事業に実際に当てはまるいくつかの締めくくりのコメント:

    • アプリケーションとすべてのデータベースクライアントプログラムは、本番環境に移行する前に、新しいメジャーPostgreSQLバージョンに対してテストする必要があります。
    • そのためには、本番環境で実行する前に、アップグレード手順もテストする必要があります。
    • 物事を書き留めるか、より良いスクリプトを作成し、可能な限り自動化します。
    • アップグレード手順中に、バックアップセットアップ、監視システム、およびメンテナンスツールとスクリプトが適切に調整されていることを確認してください。理想的には、切り替えが行われる前に、これらを適切に配置して検証する必要があります。

    それを念頭に置いて、幸運を祈り、あなたの経験を共有してください。


    1. カスタムビルド統計

    2. ProxySQL入門-MySQLとMariaDBの負荷分散チュートリアル

    3. Ora-01427の単一行サブクエリがselectで複数の行を返す問題を修正するにはどうすればよいですか?

    4. ローカルIISではOracleORA-12154エラーが発生しますが、Visual StudioDevelopmentServerではエラーが発生しません