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

PostgreSQL9.3でのスイッチオーバー/スイッチバックの実装。

    この投稿では、PostgreSQLの高可用性で適切なスイッチオーバーおよびスイッチバック環境をセットアップする方法について高度なDBAを教育します。まず、PostgreSQL9.3でスイッチオーバー/スイッチバックを簡単にしたパッチ作成者のHeikkiとFujiiに感謝します(他の名前を見逃した場合はご容赦ください)。

    これらのパッチの前に簡単に説明してみましょう。スタンバイは、迅速で安全なディザスタリカバリを実現するための重要なコンポーネントです。 PostgreSQLでは、リカバリの概念は主に、PITRの前後の一連のWALセグメントを識別するためのタイムライン、またはWALセグメントの重複を回避するためのスタンバイの昇格を扱います。タイムラインIDはWALセグメントファイル名に関連付けられています(例:-$ PGDATA / pg_xlog / 0000000C000000020000009Eセグメント「0000000C」はタイムラインIDです)。ストリーミングレプリケーションでは、プライマリとスレーブの両方が同じタイムラインIDに従いますが、スタンバイがスイッチオーバーによって新しいマスターとして昇格すると、タイムラインIDがバンプされ、古いプライマリはタイムラインIDの違いによりスタンバイとしての再起動を拒否し、次のようなエラーメッセージをスローします。

    FATAL:  requested timeline 10 is not a child of this server's history
    DETAIL: Latest checkpoint is at 2/9A000028 on timeline 9, but in the history of the requested timeline, the server forked off from that timeline at 2/99017E68.

    したがって、新しいスタンバイを最初から構築する必要があります。データベースサイズが大きい場合は、再構築に時間がかかり、この期間、新しく昇格したプライマリはスタンバイなしで実行されます。他にも問題があります。たとえば、スイッチオーバーが発生すると、プライマリがクリーンシャットダウンを実行し、Walsenderプロセスはすべての未処理のWALレコードをスタンバイに送信しますが、それらが複製されるのを待たずに終了します。 Walreceiverは、接続の閉鎖を検出して終了するため、これらの未処理のWALレコードを適用できません。

    現在、PostgreSQL 9.3の2つの主要なソフトウェア更新により、両方の問題が作成者によって非常にうまく対処され、StreamingReplicationStandbyは一貫してタイムラインスイッチに従います。再起動するだけで、スタンバイの再構築時間を大幅に短縮することで、プライマリとスタンバイの間でシームレスかつ簡単に職務を切り替えることができるようになりました。

    注:WALアーカイブが両方のサーバーにアクセスできず、スイッチオーバープロセスでプライマリデータベースがクリーンシャットダウン(通常モードまたは高速モード)を実行する必要がある場合、スイッチオーバー/スイッチバックはできません。

    デモを行うために、共通のWALアーカイブの場所を共有する2つのクラスター(プライマリとして5432、スタンバイとして5433)間でローカルVMに構成したストリーミングレプリケーションのセットアップ(ウィキからSRのセットアップ)から始めましょう。両方のクラスターが完全にアクセスできる必要があるためです。 WALアーカイブのシーケンスの。コンセプトをよりよく理解するために、セットアップの詳細と現在のタイムラインIDとともに以下で共有されているスナップショットを見てください。

    この段階では、スイッチオーバーとスイッチバックが計画されたアクティビティであることを誰もがしっかりと理解している必要があります。これでSRのセットアップが完了し、以下に示すようにプライマリとスタンバイの役割を交換できます。

    切り替え手順:

    ステップ1。 プライマリ[5432]のクリーンシャットダウンを実行します(-m高速またはスマート)

    [postgres@localhost:/~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data stop -mf
    waiting for server to shut down.... done
    server stopped

    ステップ2。 昇格する前に、スタンバイ[5433]の同期ステータスとリカバリステータスを確認してください:

    [postgres@localhost:/opt/PostgreSQL/9.3~]$  psql -p 5433 -c 'select pg_last_xlog_receive_location() "receive_location",
    pg_last_xlog_replay_location() "replay_location",
    pg_is_in_recovery() "recovery_status";'
    receive_location | replay_location | recovery_status
    ------------------+-----------------+-----------------
    2/9F000A20 | 2/9F000A20 | t
    (1 row)

    完全同期でスタンバイ。この段階では、プライマリとして安全に宣伝できます。
    ステップ3。 pg_ctlプロモートまたはトリガーファイルの作成により、スタンバイを新しいプライマリとして開きます。

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ grep trigger_file data_slave/recovery.conf
    trigger_file = '/tmp/primary_down.txt'
    [postgres@localhost:/opt/PostgreSQL/9.3~]$ touch /tmp/primary_down.txt

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ psql -p 5433 -c "select pg_is_in_recovery();"
    pg_is_in_recovery
    -------------------
    f
    (1 row)

    In Logs:
    2014-12-29 00:16:04 PST-26344-- [host=] LOG: trigger file found: /tmp/primary_down.txt
    2014-12-29 00:16:04 PST-26344-- [host=] LOG: redo done at 2/A0000028
    2014-12-29 00:16:04 PST-26344-- [host=] LOG: selected new timeline ID: 14
    2014-12-29 00:16:04 PST-26344-- [host=] LOG: restored log file "0000000D.history" from archive
    2014-12-29 00:16:04 PST-26344-- [host=] LOG: archive recovery complete
    2014-12-29 00:16:04 PST-26342-- [host=] LOG: database system is ready to accept connections
    2014-12-29 00:16:04 PST-31874-- [host=] LOG: autovacuum launcher started

    スタンバイがマスターとして昇格し、新しいタイムラインが続き、ログで確認できます。
    ステップ4。 古いプライマリをスタンバイとして再起動し、$ PGDATA /recovery.confファイルで「recovery_target_timline=’latest'」を渡すことにより、新しいタイムラインに従うことができます。

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ cat data/recovery.conf
    recovery_target_timeline = 'latest'
    standby_mode = on
    primary_conninfo = 'host=localhost port=5433 user=postgres'
    restore_command = 'cp /opt/PostgreSQL/9.3/archives93/%f %p'
    trigger_file = '/tmp/primary_131_down.txt'
    [postgres@localhost:/opt/PostgreSQL/9.3~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data start
    server starting

    Recovery.confを実行すると、古いプライマリが新しいスタンバイとして5433ポートに接続しようとし、共通のWALアーカイブの場所を指していることが非常に明確になります。

    In Logs:
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: database system was shut down at 2014-12-29 00:12:23 PST
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000E.history" from archive
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: entering standby mode
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000D00000002000000A0" from archive
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: restored log file "0000000D.history" from archive
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: consistent recovery state reached at 2/A0000090
    2014-12-29 00:21:17 PST-32315-- [host=] LOG: record with zero length at 2/A0000090
    2014-12-29 00:21:17 PST-32310-- [host=] LOG: database system is ready to accept read only connections
    2014-12-29 00:21:17 PST-32325-- [host=] LOG: started streaming WAL from primary at 2/A0000000 on timeline 14

    ステップ5。 新しいスタンバイステータスを確認します。

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ psql -p 5432 -c "select pg_is_in_recovery();"
    pg_is_in_recovery
    -------------------
    t
    (1 row)

    再セットアップせずに、古いプライマリを新しいスタンバイとして戻しました。

    スイッチバック手順:

    ステップ1。 新しいプライマリのクリーンシャットダウンを実行します[5433]:

    [postgres@localhost:/opt/~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_slave stop -mf
    waiting for server to shut down.... done
    server stopped

    ステップ2。 プロモートする前に、新しいスタンバイ[5432]の同期ステータスを確認してください。
    ステップ3。 トリガーファイルまたはpg_ctlプロモートを作成して、新しいスタンバイ[5432]をプライマリとして開きます。

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ touch /tmp/primary_131_down.txt

    ステップ4。 再起動により、新しいプライマリ[5433]が新しいスタンバイとして停止しました。

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ more data_slave/recovery.conf
    recovery_target_timeline = 'latest'
    standby_mode = on
    primary_conninfo = 'host=localhost port=5432 user=postgres'
    restore_command = 'cp /opt/PostgreSQL/9.3/archives93/%f %p'
    trigger_file = '/tmp/primary_down.txt'

    [postgres@localhost:/opt/PostgreSQL/9.3~]$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_slave start
    server starting

    新しいスタンバイのログを確認できます。

    In logs:
    [postgres@localhost:/opt/PostgreSQL/9.3/data_slave/pg_log~]$ more postgresql-2014-12-29_003655.log
    2014-12-29 00:36:55 PST-919-- [host=] LOG: database system was shut down at 2014-12-29 00:34:01 PST
    2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000F.history" from archive
    2014-12-29 00:36:55 PST-919-- [host=] LOG: entering standby mode
    2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000F.history" from archive
    2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000E00000002000000A1" from archive
    2014-12-29 00:36:55 PST-919-- [host=] LOG: restored log file "0000000E.history" from archive
    2014-12-29 00:36:55 PST-919-- [host=] LOG: consistent recovery state reached at 2/A1000090
    2014-12-29 00:36:55 PST-919-- [host=] LOG: record with zero length at 2/A1000090
    2014-12-29 00:36:55 PST-914-- [host=] LOG: database system is ready to accept read only connections
    2014-12-29 00:36:55 PST-929-- [host=] LOG: started streaming WAL from primary at 2/A1000000 on timeline 15
    2014-12-29 00:36:56 PST-919-- [host=] LOG: redo starts at 2/A1000090

    非常に素晴らしいです。時間がないのに、プライマリサーバーとスタンバイサーバーの役割を切り替えました。各プロモーションのログからタイムラインIDの増分に気付くことさえできます。

    他の人と同じように、私の投稿はすべて知識共有の一部です。コメントや修正は大歓迎です。 🙂


    1. SQL Serverチュートリアル–Transact-SQLをマスターするために必要なすべて

    2. SQLiteクエリ結果を列ヘッダー付きの列としてフォーマットする

    3. 11基本的な例を含む一般的なSQLステートメント

    4. SQLエラー:ORA-02000:ID列ベースの表を作成するときにALWAYSキーワードがありません