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

PGpoolのガイド-ヒントと観察:パート3-

    前のパートでは、実装されていない機能をあえて試してみて、それがどのように機能するかを想像しました。そもそもHAは設計の問題であり、それから実装の問題です。それは悪い実装を許しませんし、素朴なデザインをスマートに見せることもできません。しかし、考えられるすべてのシナリオをカバーし、ほとんどの場合に適切な最良のルールを見つけた後、非常に原始的な小さな変更が拠点を台無しにすることがあります。以下でサンドボックスを作成します。

    pgpoolがフェイルオーバーする必要があるができない場合はどうなりますか?

    マスターのヘルスチェックが失敗すると、failover_commandが起動され、すべてが縮退するか、次のスレーブがプライマリに昇格します。しっかりしているように聞こえます。それ自体が失敗した場合はどうなりますか?たとえば、ssh接続が失敗した場合(たとえば、other --bad adminが〜/ .ssh / authorized_keysからキーを削除したため)。何がありますか?

    health_check_timeout(デフォルトは20)がなくなるとすぐに(再試行遅延、最大リタイアなどの影響も受けます)、ノードは停止します。したがって、次のようになります。

    t=# select nid,port,st 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
    -----+------+------
       0 | 5400 | down
       1 | 5401 | up
       2 | 5402 | up
    (3 rows)

    したがって、再試行は残りませんでした。フェイルオーバーは失敗しました。最初のオプションは、明らかに手動でフェイルオーバーを実行することです。しかし、なんらかの愚かなエラーが原因でフェイルオーバーが失敗した場合、マスターはレールに戻ります。唯一の問題は、マスターがオフラインであるとpgpoolが考えることです。おそらく、事故前の状態のままにしておくことをお勧めします。もちろん、マスターをオンラインに戻すだけでは十分ではありません。 Pgpoolはすでにプライマリを「縮退」させています。新しいノードとして追加するだけでも役に立ちません。最悪のことは、イベント後、pgpoolは古いマスターがpg_is_in_recovery()であるかどうかをチェックしようとしないため、プライマリとして受け入れないことです。バグトラックによると、pgpool-Dコマンドを使用して「pgpool_statusファイルを破棄し、以前のステータスを復元しない」必要があります。

    ステータスを破棄した後、サーバーが予期せず接続を閉じて実行するのを防ぐために再接続します:

    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 | up | primary
       1 | 5401 | up | standby
       2 | 5402 | up | standby
    (3 rows)

    すべてのノードがバックアップされて実行され、pgpoolがマスターを認識します。

    最後に、pgpoolの使用に関するヒントと所見をいくつか取り上げたいと思います:

    • バックエンド設定の変更は少し注意が必要です。ホスト名、ポート、およびディレクトリは、新しいノードを追加するためにリロードする必要がありますが、既存のノードを編集するには再起動する必要があります。重量と旗はリロードするだけで変更できます。

    • load_balance_node列の値を構成と混同しないでください。 trueのノードが1つだけ表示された場合、それは単にOKではありません-それはそういう意味です。バランシングプールにノードが1つしかないという意味ではなく、この特定のセッションでどのノードが選択されているかを示しているだけです。以下は、ノードID 2が選択された、SELECTステートメントバランシングに参加している3つのノードすべてのクエリ結果です。

      t=# show pool_nodes;
       node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay
      ---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
       0       | localhost | 5400 | up     | 0.125000  | primary | 61         | false             | 0
       1       | localhost | 5401 | up     | 0.312500  | standby | 8          | false             | 0
       2       | localhost | 5402 | up     | 0.562500  | standby | 11         | true              | 0
      (3 rows)
    • show pool_nodesを使用して、負荷分散に選択されたノードを確認できますが、「show」ノードではなく、クエリでそのノードを知っておく必要があるため、このような確認は必ずしも十分な情報を提供するわけではありません。次のようにして、現在のクエリに使用しているノードを監視できます。

      t=# select *,current_setting('port') from now();
                    now              | current_setting
      -------------------------------+-----------------
       2018-04-09 13:56:17.501779+01 | 5401
      (1 row)

    重要!しかし、そうではありません:

    t=# select now, setting from now() join pg_settings on name='port';
                 now             | setting
    -----------------------------+---------
     2018-04-09 13:57:17.5229+01 | 5400
    (1 row)

    常にマスターのポートを返します。同じことがpg_catalogSELECTにも当てはまります。

    • 前の部分で気づいたように、私は、単にpool_nodesを表示してノードを状態とともにリストするよりも、より複雑な方法を使用します。結果を管理しやすくする方法を示すために、意図的に行います。 whereを使用するとクエリが長くなりますが、結果は明確になり、特定のタスクの注意をそらすものをすべてスキップします。比較:

    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 | up | primary
       1 | 5401 | up | standby
       2 | 5402 | up | standby

    初期のshowpool_nodesの出力で...

    • pgbouncerとpgpoolを比較することはできません。ただし、そうする場合は、pgpoolでのクエリの解析がpgのバージョンに依存することを知っておくことが最も重要です。したがって、postgreSQLをアップグレードするときは、pgpoolもアップグレードする必要がありますが、1つのpgbouncerインスタンスは、同じiniファイル内の8,9,10個の異なるクラスターの構成を持つことができます。

    • pgpoolの代わりにフェイルオーバースクリプトだけを使用できないのはなぜですか?あなたはできる。しかし、pgpoolは、memcachedと接続プール、バランシング、スプリットブレイン制御とともにそれを提供し、数十年の使用によってチェックされます。

    • バグ追跡システムが導入されています。pgpoolを使用している場合は、このシステムにアクセスする価値があります:https://www.pgpool.net/mantisbt/my_view_page.php

    • bakance(backend + balance?..)、statemnet、allowed、またはバージョン間での不一致(pool_nodesはintでしたが、現在はenumですが、pcp_node-infoの古い値へのリンクはまだあります)などのドキュメントの多くのタイプミスが印象を台無しにしますこの素晴らしい製品について。ただし、ドキュメントで見つかった「バグ」に関するレポートを送信するフォーム(postgresドキュメントの「修正を送信」のように)を使用すると、大幅に改善されます。

    • 重要なヒント: ステップに頼る前に-それをチェックしてください。例えば。ノードをプロモートした後は、再プロモートできません(ここでは、プロモートはpostgres操作ではなく、pgpoolのマスターとしてのノードの登録です):

      [email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1
      pcp_promote_node -- Command Successful
      [email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1
      FATAL:  invalid pgpool mode for process recovery request
      DETAIL:  specified node is already primary node, can't promote node id 1

    論理的に聞こえ、見栄えがします。ただし、これを間違ったノードに対して実行した場合(たとえば、ノード0は!pg_is_in_recovery):

    [email protected]:~# for i in $(seq 1 3); do pcp_promote_node -w -h 127.0.0.1 -U vao -n 0; echo $?; done
    pcp_promote_node -- Command Successful
    0
    pcp_promote_node -- Command Successful
    0
    pcp_promote_node -- Command Successful
    0

    ノードを再プロモートしてエラーを予期できないため、これは悪いことですが、終了ステータスは0になります…

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

    重要なヒント:あまりプレイしないでください。製品でプレイしないでください!

    pg_rewindを使用してrecovery_1st_stage_commandで遊んで、好奇心から別のモンキーハックを試してみようと思いました-引数なしでpgpool_recovery()をクエリし(とにかくセットアップでは無視します)、ノードをpgpoolに接続しようとしました:

    [email protected]:~# psql -p 5433 -h localhost template1 -c "SELECT pgpool_recovery('or_1st.sh', '', '', '')"
     pgpool_recovery
    -----------------
     t
    (1 row)
    
    [email protected]:~# pcp_attach_node -h 127.0.0.1 -U vao -w -n 1
    pcp_attach_node -- Command Successful

    このばかげた考えは私を次のように導きました:

    [email protected]:~# ps -aef | grep pgpool
    postgres 15227     1  0 11:22 ?        00:00:00 pgpool -D
    postgres 15240 15227  0 11:22 ?        00:00:00 pgpool: health check process(0)
    postgres 15241 15227  0 11:22 ?        00:00:00 pgpool: health check process(1)
    postgres 15242 15227  0 11:22 ?        00:00:00 pgpool: health check process(2)
    postgres 15648 15227  0 11:24 ?        00:00:00 [pgpool] <defunct>
    postgres 16264 15227  0 11:26 ?        00:00:00 pgpool: PCP: wait for connection request
    postgres 16266 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
    postgres 16506 16264  0 11:26 ?        00:00:00 pgpool: PCP: processing recovery request
    postgres 16560 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
    postgres 16835 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
    postgres 16836 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>

    逃げる必要はありません:

    [email protected]:~# kill -9 
    [email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.5433
    [email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.9898

    5433より上はpgpoolポートで、9898はpcpポートです。明らかにクラッシュ後、ファイルはスイープされないため、手動で行う必要があります。

    • pgpoolを本番環境に移行する前に、よく読んでたくさん遊んでください。 pgpoolでヘルプを見つけてからpostgres自体を見つけるのははるかに困難です。いくつかの質問は決して答えられません。特に間違った場所で尋ねられたとき(私は答えを得るために正しい場所に基づいて答えました)...
    • カスケードレプリケーションの最新のタイムラインを忘れないでください(実際にはpgpoolのヒントではありませんが、多くの場合、新しいマスターを取得するには、レシーバーの適切なエンドポイントを指定するだけでは不十分であることを理解していません)。
    • 図付きのアーキテクチャはここにあります。

    結論

    10年以内に、新しい有望な機能(ウォッチドッグと仮想IP)と重要な修正(例:serialize_accept)が登場しましたが、全体的には過小評価された印象を残しています。ドキュメントには、10年間そこに住んでいるタイプミスがあります。誰もドキュメントを読んでいないと思います。誰も気づかなかったと思います。簡単な方法でそれらを報告することはできません。たくさんの銃が装填されて準備されており、初心者ユーザーが取り、足を指してトリガーを引くためのドキュメンテーションサイトに横たわっています。私はそれをどのように改善するかについて合理的な考えがありません-私はただ射手に警告しているだけです。 1つのパラメータを誤って解釈すると、間違いを見つけるためにリバースエンジニアリングの絶望的な立場に陥る可能性があります。ここ数年、pgpoolは、上級ユーザー向けの製品であり、現在もそのような製品です。ドキュメントを読むシャーロックホームズについての古いロシアのジョークを思い出さずにはいられませんでした。シャーロックとワトソンは気球で飛んでいます。突然、強風が彼らを数千マイル離れたところに吹き飛ばします。彼らが着陸できるとき、彼らは女の子が羊を放牧しているのを見る。ホームズは女の子に尋ねます:「ダーリン、私たちはどこにいますか?」そして女の子は「あなたは気球に乗っています!」と答えます。シャーロックは感謝し、彼らが離陸すると、「風が私たちを非常に遠くまで連れて行った-私たちはロシアにいる」と言っています。 「でもどうやって知ってるの?」ワトソンは尋ねます。 「それは明らかです。ロシアのコーダーだけが羊をかすめています」とSherlockは答えます。 「しかし、女の子がコーダーであることをどうやって知っていますか?」 -「それは明らかです-彼女は私たちに絶対に正確でまったく役に立たない答えを与えました」。


    1. SQL Serverで、特定のテーブルに対してCREATE TABLEステートメントを生成するにはどうすればよいですか?

    2. バックエンドパフォーマンスの改善パート2/3:データベースインデックスの使用

    3. ADODFCMPユーティリティ

    4. バックアップ前のリカバリ要件