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

PostgreSQL用Pgpoolのガイド:パート2

    これは、ブログ「PostgreSQL用Pgpoolのガイド」の第2部です。負荷分散、セッションプーリング、メモリキャッシュ、およびインストールに関する最初の部分は、ここにあります。

    多くのユーザーは、特に高可用性機能のためにpgpoolに目を向けており、提供できるものはたくさんあります。ウェブ上にはpgpoolHAに関する説明がかなりたくさんあるので(たとえば、長いものと短いもの)、それらを繰り返すのは意味がありません。また、構成値のさらに別のブラインドセットを提供する必要もありません。代わりに、ルールに反して、間違った方法で試してみることをお勧めします。そうすれば、いくつかの興味深い動作が見られます。期待される最も重要な機能の1つ(少なくともページの上部にあります)は、「死んだ」元マスターの使いやすさを認識し、pg_rewindで再利用する機能です。ビッグデータで新しいスタンバイを戻す時間を節約できます(rsyncまたはpg_basebackupをスキップして、新しいマスターからすべてのファイルを効果的にコピーします)。厳密に言えば、pg_rewindは、計画されたフェイルオーバー(アップグレード中または新しいハードウェアへの移行中)を対象としています。ただし、計画されていないが正常なシャットダウンと自動フェイルオーバーに非常に役立つ場合があります。たとえば、ClusterControlは、レプリケーションスレーブの自動フェイルオーバーを実行するときにこれを利用します。ケースがあると仮定しましょう。可能な限り(任意の)マスターにアクセスできる必要があります。何らかの理由(ネットワーク障害、最大接続数の超過、または新しいセッションの開始を禁止するその他の「障害」)でRW操作にマスターを使用できなくなった場合、接続を受け入れることができるスレーブを備えたフェールオーバークラスターが構成されています。その後、スレーブの1つを昇格させ、それにフェイルオーバーできます。

    まず、3つのノードがあると仮定します。

    • 10.1.10.124:5400 with / pg / 10 / m(pgpoolもここで回転します)
    • 10.1.10.147:5401 with / pg / 10 / m2
    • 10.1.10.124:5402 with / pg / 10 / s2

    これらは実質的にパート1と同じノードですが、フェイルオーバーノードは別のホストと$PGDATAに移動されます。リモートsshコマンドでタイプミスしたり、余分な引用符を忘れたりしないようにするために行いました。また、IPアドレスが異なるため、デバッグ情報はより単純に見えます。最後に、このサポートされていないユースケースを機能させることができるかどうか確信が持てなかったため、自分の目で確認する必要があります。

    フェイルオーバー

    まず、failover_commandを設定し、pgpool reloadを実行して、フェイルオーバーを試みます。こことさらに、pgpoolサーバーの/ tmp / dに情報をエコーするので、-f / tmp/dを調整してフローを確認できます。

    [email protected]:~$ grep failover_command /etc/pgpool2/pgpool.conf
    failover_command = 'bash /pg/10/fo.sh %D %H %R'
    
    [email protected]:~$ cat /pg/10/fo.sh
    rem_cmd="pg_ctl -D $3 promote"
    cmd="ssh -T [email protected]$2 $rem_cmd"
    echo "$(date) $cmd" >>/tmp/d
    $cmd &>>/tmp/d

    注意:リモートホストの.bashrcに$ PATHを設定していますか?..

    マスターを止めましょう(災害が発生する方法ではないことを私は知っています、少なくともいくつかの巨大な猿または赤い輝くロボットが巨大なハンマーでサーバーを粉砕するか、少なくとも退屈なハードディスクが死ぬことを期待していますが、私はこれを優雅に使用していますpg_rewindの使用の可能性をデモするためのバリアントであるため、ここでフェイルオーバーは、health_check_periodの0.5秒前の人為的エラーまたはネットワーク障害の結果になります。したがって:

    /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m stop
    2018-04-18 13:53:55.469 IST [27433]  LOG:  received fast shutdown request
    waiting for server to shut down....2018-04-18 13:53:55.478 IST [27433]  LOG:  aborting any active transactions
    2018-04-18 13:53:55.479 IST [28855] postgres t FATAL:  terminating connection due to administrator command
    2018-04-18 13:53:55.483 IST [27433]  LOG:  worker process: logical replication launcher (PID 27440) exited with exit code 1
    2018-04-18 13:53:55.484 IST [27435]  LOG:  shutting down
    2018-04-18 13:53:55.521 IST [27433]  LOG:  database system is shut down
     done
    server stopped

    次に、フェイルオーバーコマンドの出力を確認します:

    [email protected]:~$ cat /tmp/d
    Wed Apr 18 13:54:05 IST 2018 ssh -T [email protected]
    pg_ctl -D /pg/10/f promote
    waiting for server to promote.... done
    server promoted

    そしてしばらくして確認します:

    t=# select nid,port,st, role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
     nid | port |  st  |  role
    -----+------+------+---------
       0 | 5400 | down | standby
       1 | 5401 | up   | primary
       2 | 5402 | up   | standby
    (3 rows)

    また、フェールオーバー前のクラスターログにも表示されます:

    2018-04-13 14:26:20.823 IST [20713]  LOG:  received promote request
    2018-04-13 14:26:20.823 IST [20713]  LOG:  redo done at 0/951EC20
    2018-04-13 14:26:20.823 IST [20713]  LOG:  last completed transaction was at log time 2018-04-13 10:41:54.355274+01
    2018-04-13 14:26:20.872 IST [20713]  LOG:  selected new timeline ID: 2
    2018-04-13 14:26:20.966 IST [20713]  LOG:  archive recovery complete
    2018-04-13 14:26:20.998 IST [20712]  LOG:  database system is ready to accept connections

    レプリケーションの確認:

    [email protected]:~$ psql -p 5401 t -c "select now() into test"
    SELECT 1
    [email protected]:~$ psql -p 5402 t -c "select * from test"
                  now
    -------------------------------
     2018-04-13 14:33:19.569245+01
    (1 row)

    スレーブ/pg/ 10 / s2:5402は、recovery_target_timeline =のrecovery.confの最新のおかげで新しいタイムラインに切り替えられたので、問題ありません。新しいマスターを指すようにrecovery.confを調整する必要はありません。これは、pgpool ipとportを指し、誰がプライマリマスターの役割を果たしているかに関係なく同じままであるためです。

    負荷分散の確認:

    [email protected]:~$ (for i in $(seq 1 9); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
          6 5401
          3 5402

    良い。 pgpoolの背後にあるアプリは、2回目の停止に気づき、引き続き機能します。

    元マスターの再利用

    これで、元マスターをフェイルオーバースタンバイに切り替えて、元に戻すことができます(pgpoolに新しいノードがすでに存在するため、新しいノードを追加する必要はありません)。 wal_log_hintsを有効にしていない場合、またはデータチェックサムを使用していない場合(これらのオプションの包括的な違いはここにあります)、新しいタイムラインに従うには、元マスターでクラスターを再作成する必要があります。

    [email protected]:~$ rm -fr /pg/10/m
    [email protected]:~$ pg_basebackup -h localhost -p 5401 -D /pg/10/m/

    ただし、急いで上記のステートメントを実行しないでください。 wal_log_hints(再起動が必要)に注意した場合は、pg_rewindを使用して、元マスターから新しいスレーブへの切り替えを大幅に高速化できます。

    つまり、ATMでは元マスターがオフラインになり、次のタイムラインを持つ新しいマスターが開始されます。元マスターが一時的なネットワーク障害のためにオフラインになっていて、戻ってきた場合は、最初にシャットダウンする必要があります。上記の場合、ダウンしていることがわかっているので、巻き戻しを試すことができます:

    [email protected]:~$ pg_rewind -D /pg/10/m2 --source-server="port=5401 host=10.1.10.147"
    servers diverged at WAL location 0/40605C0 on timeline 2
    rewinding from last common checkpoint at 0/4060550 on timeline 2
    Done!

    そして再び:

    [email protected]:~$ pg_ctl -D /pg/10/m2 start
    server started
    ...blah blah 
    [email protected]:~$ 2018-04-16 12:08:50.303 IST [24699]  LOG:  started streaming WAL from primary at 0/B000000 on timeline 2
    
    t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
     nid | port |  st  |  role
    -----+------+------+---------
       0 | 5400 | down | standby
       1 | 5401 | up   | primary
       2 | 5402 | up   | standby
    (3 rows)

    Ops。えっ!ポート5400のクラスターはオンラインであり、新しいタイムラインに従っているという事実にもかかわらず、pgpoolにそれを認識するように指示する必要があります:

    [email protected]:~$ pcp_attach_node -w -h 127.0.0.1 -U vao -n 0
     pcp_attach_node  -- Command Successful

    これで、3つすべてが稼働し(そしてpgpoolはそれを認識し)、同期します:

    [email protected]:~$ sql="select ts.i::timestamp(0), current_setting('data_directory'),case when pg_is_in_recovery() then 'recovering' else 'mastering' end stream from ts order by ts desc"
    [email protected]:~$ psql -h 10.1.10.147 -p 5401 t -c "$sql";
              i          | current_setting |  stream
    ---------------------+-----------------+-----------
     2018-04-30 14:34:36 | /pg/10/m2       | mastering
    (1 row)
    
    [email protected]:~$ psql -h 10.1.10.124 -p 5402 t -c "$sql";
              i          | current_setting |   stream
    ---------------------+-----------------+------------
     2018-04-30 14:34:36 | /pg/10/s2       | recovering
    (1 row)
    
    [email protected]:~$ psql -h 10.1.10.124 -p 5400 t -c "$sql";
              i          | current_setting |   stream
    ---------------------+-----------------+------------
     2018-04-30 14:34:36 | /pg/10/m        | recovering
    (1 row)

    次に、recovery_1st_stage_commandを使用して元マスターを再利用してみます:

    [email protected]:~# grep 1st /etc/pgpool2/pgpool.conf
    recovery_1st_stage_command = 'or_1st.sh'

    しかし、recovery_1st_stage_commandは、pg_rewindに必要な引数を提供していません。これは、recovery_1st_stage_commandに追加するとわかります。

    echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4"; exit 1;

    出力:

    online recovery started on u2 2018-04-30 /pg/10/m2/or_1st.sh /pg/10/m2 10.1.10.124 /pg/10/m 5401

    ええと-pg_rewindの使用はやることリストにあります-私は何を期待していましたか?..マスターIPとポートを取得するためにモンキーハックを行う必要があります(フェイルオーバー後も変更され続けることを忘れないでください)。

    今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする

    モンキーハック

    だから私はrecovery_1st_stage_commandにこのようなものがあります:

    [email protected]:~# cat /pg/10/or_1st.sh
    pgpool_host=10.1.10.124
    pgpool_port=5433
    echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4" | ssh -T $pgpool_host "cat >> /tmp/d"
    master_port=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select port from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role='primary'")
    master_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role='primary'")
    failover_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role!='primary' order by port limit 1")
    src='"port=$master_port host=$master_host"'
    rem_cmd="'pg_rewind -D $3 --source-server=\"port=$master_port host=$master_host\"'"
    cmd="ssh -T $failover_host $rem_cmd"
    echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
    $cmd
    
    tmp=/tmp/rec_file_tmp
    cat > $tmp <<EOF
    standby_mode          = 'on'
    primary_conninfo      = 'host=$master_host port=$master_port user=postgres'
    trigger_file = '/tmp/tg_file'
    recovery_target_timeline  = latest
    EOF
    
    scp $tmp $failover_host:$3/recovery.conf
    
    rem_cmd="pg_ctl -D $3 start"
    cmd="ssh -T $failover_host $rem_cmd"
    echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
    $cmd
    echo "OR finished $(date --iso-8601)" | ssh -T $pgpool_host "cat >> /tmp/d"
    exit 0;

    今、なんてめちゃくちゃ!ええと-既存の機能を使用しないことにした場合-準備してください-見た目が悪くなり、動作が悪くなり、自分がしたことを永久に恥ずかしく思うでしょう。だからステップバイステップ:

    • 「showpool_nodes」のクエリとステップのログ記録、コマンドの実行の両方にリモート接続するには、pgpoolIPとポートが必要です。
    • コマンドはマスター側で実行され、フェイルオーバー後に変更されるため、いくつかのdbg情報をssh経由で/ tmp/dにパイプしています
    • 「showpool_nodes」の結果を使用して、WHERE句でフィルタリングするだけで実行中のマスター接続情報を取得できます
    • pg_rewindの引数に二重引用符が必要です。これはsshで実行する必要があるため、読みやすくするためにコマンドを分割し、エコーして実行します
    • 「showpool_nodes」からの出力に基づいてrecovery.confを準備します(自分自身に問いかけます。代わりにpgpool IPとポートを使用しなかったのはなぜですか?..
    • 新しいフェイルオーバースレーブを開始します(2番目のステップを使用することになっています。すべてのIPとポートを再度取得しないようにスキップしました)

    残っているのは、この混乱をpcpで使おうとしていることです:

    [email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 0 -w
    pcp_recovery_node -- Command Successful
    [email protected]:~# psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
     nid | port | st |  role
    -----+------+----+---------
       0 | 5400 | up | standby
       1 | 5401 | up | primary
       2 | 5402 | up | standby
    (3 rows)

    pgpoolサーバーの/tmp/ dを確認します:

    [email protected]:~# cat /tmp/d
    Tue May  1 11:37:59 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m2 promote
    waiting for server to promote.... done
    server promoted
    online recovery started on u2 2018-05-01 /pg/10/m2/or_1st.sh /pg/10/m2
    ssh -T 10.1.10.124 'pg_rewind -D --source-server="port=5401 host=10.1.10.147"'
    ssh -T 10.1.10.124 pg_ctl -D start
    OR finished 2018-05-01

    ここで、明らかにもう一度ロールオーバーして、任意のホストで機能するかどうかを確認します。

    [email protected]:~$ ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 stop             waiting for server to shut down.... done
    server stopped
    [email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
     nid | port |  st  |  role
    -----+------+------+---------
       0 | 5400 | up   | primary
       1 | 5401 | down | standby
       2 | 5402 | up   | standby
    (3 rows)
    
    [email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 1 -w
    
    [email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
     nid | port | st |  role
    -----+------+----+---------
       0 | 5400 | up | primary
       1 | 5401 | up | standby
       2 | 5402 | up | standby
    (3 rows)

    ログは似ています-IPとポートのみが変更されました:

     Tue May  1 11:44:01 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m promote
    waiting for server to promote.... done
    server promoted
    online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m 10.1.10.147 /pg/10/m2 5400
    ssh -T 10.1.10.147 'pg_rewind -D /pg/10/m2 --source-server="port=5400 host=10.1.10.124"'
    ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 start
    online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m
    ssh -T 10.1.10.147 'pg_rewind -D --source-server="port=5400 host=10.1.10.124"'
    ssh -T 10.1.10.147 pg_ctl -D start
    OR finished 2018-05-01

    このサンドボックスでは、マスターはフェイルオーバー時に5401に移動し、しばらくそこに住んでいた後、5400に戻りました。pg_rewindを使用すると、可能な限り高速になります。以前は、自動フェイルオーバーの恐ろしい部分は、構成を実際に台無しにして、強制的な操作を予測しなかった場合、空きスレーブがなくなるまで、次のスレーブと次のスレーブへの自動フェイルオーバーに遭遇する可能性がありました。その後、いくつかのスプリットブレインマスターが作成され、フェイルオーバースペアがなくなります。このようなシナリオでは、フェイルオーバーするスレーブがさらに多くなるのは悪い慰めですが、pg_rewindがなければ、それすらありません。 「従来の」rsyncまたはpg_basebackupは、すべての$ PGDATAをコピーしてスタンバイを作成し、「それほど変わらない」元マスターを再利用することはできません。

    この実験の結論として、もう一度強調したいと思います。これは、ブラインドコピーによる貼り付けに適したソリューションではありません。 pg_poolではpg_rewindの使用は推奨されていません。 ATMでは全く使えません。私のようなnubesがそれがどのように機能するかをもう少し詳しく観察するために、pgpoolHA構成に新鮮な空気を追加したかったのです。 coryphaeusが素朴なアプローチに微笑んで、多分私たちの-nubesの目でそれを見るために。


    1. DROPとTRUNCATETABLEはログに記録されないという神話

    2. OracleDatabase20cの新機能

    3. エラーORA-01804のテキストを取得しようとしたときにエラーが発生しました

    4. Amazon RelationalDatabaseServiceのメリットとセキュリティ