Maintenance commands through proxies#

メンテナンスとパフォーマンス#

原則として、クラスターの書き込みリーダーではメンテナンス操作を実行しないでください。 VACUUM などのメンテナンス操作は、ビジー状態のサーバーのスムーズな実行に非常に混乱をもたらし、多くの場合ワークロードのパフォーマンスに悪影響を与える可能性があります。したがって、書き込みリーダーではないグループ内のノードでメンテナンスコマンドを実行することをお勧めします。通常、これには、非書き込みリーダーノードで直接接続し、メンテナンスコマンドを発行する必要があります。しかし、状況によっては、これは不可能です。

メンテナンスとプロキシ#

プロキシは、デザイン、常に現在の書き込みリーダーに接続し、コマンドを送信します。これは、通常、メンテナンスを実行するためにプロキシを介して接続する必要がないことを意味します。 PGDクラスターノードは、これらのノードでサーバーにメンテナンスコマンドを発行するために使用できるpsqlおよびPGD CLIクライアントの直接接続を提示できます。ただし、プロキシがクラスターにアクセスする唯一の方法であるPGDクラスターが展開される環境があります。

たとえば、BigAnimalでは、 PGDクラスターはロックダウンされ、データベースへのアクセスのみがPGDプロキシのインスタンスを介して行われます。この構成は、クラスターのフットプリントを削減し、安全性を高めます。ただし、別の方法を使用してメンテナンス要求をクラスターのノードに送信する必要があります。

ここで概要を説明する技術は、一般に特定のノードのサーバーに直接接続せずにコマンドをディスパッチする場合に役立ちます。

メンテナンスコマンド#

メンテナンスコマンド とは、次のことを指します。

  • VACUUM

  • 非レプリケートDDLコマンド手動複製が必要になる場合があります。

ノード名に関する注意#

クラスター内のサーバーは、PGDクラスターノード名で参照されます。クラスター内のノード名のリストを取得するには、次を使用します。

select node_name from bdr.node;

Tip

詳細については、 bdr.node_config テーブルを参照してください。 !!!

このコマンドは、ノード名のみをリストします。彼らがメンバーであるグループを知る必要がある場合は、次を使用します。

select node_name, node_group_name from bdr.node_summary;

Tip

詳細については、 bdr.node_summary テーブルを参照してください。 !!!

書き込みリーダーを見つける#

プロキシを介して接続している場合、書き込みリーダーに接続しています。 select node_name from bdr.local_node_summary を実行して、ノードの名前を確認します。

select node_name from bdr.local_node_summary;
__OUTPUT__
    node_name
- -----------------
node-two
(1 row)

これは、メンテナンスタスクを実行したくないノードです。

select * from bdr.node_group_routing_summary;
__OUTPUT__
 node_group_name |    write_lead    | previous_write_lead |       read_nodes
- ----------------+------------------+---------------------+-------------------------
 dc1             | node-two         | node-one            | {node-one,node-three}

write_lead は、前に決定したノードnode-twoであり、2つのread_nodes node-oneおよびnode-threeも見ることができます。これらのノードでは、メンテナンスを安全に実行できます。

Tip

単一のクエリーでその操作を実行できます。

select read_nodes from bdr.node_group_routing_summary where write_lead = (select node_name from bdr.local_node_summary);

PGDには、 bdr.run_on_nodes() ファンクションを使用して、特定のノードで特定のコマンドを実行する機能があります。このファンクションは、ノード名の配列と、これらのノードで実行するコマンドの2つのパラメーターを受け取ります。例

SELECT bdr.run_on_nodes(ARRAY[node-one,node-three],vacuum full foo);
__OUTPUT__

                                                                run_on_nodes
- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [{"dsn": "host=host-one port=5444 dbname=bdrdb", "node_id": "807899305", "response": {"command_status": "VACUUM"}, "node_name": "node-one", "query_send_time": "2024-01-16 16:24:35.418323+00"}, {"dsn": "host=host-three port=5432 dbname=bdrdb", "node_id": "199017004", "response": {"command_status": "VACUUM"}, "node_name": "node", "query_send_time": "2024-01-16 16:24:35.4542+00"}]

このコマンドは、 node-1およびnode-threeでvacuum full foo コマンドを実行します。ノード名は配列でファンクションに渡されます。

bdr.run_on_nodes ファンクションは、結果をJSONBとして報告します。結果には、ノードの名前と、コマンドの実行からの応答またはエラーメッセージが含まれます。含まれる他のフィールドは、含まれる場合と関連しない場合があります。

結果は単一の文字列として表示されますが、読みにくいです。この文字列にいくつかのフォーマットを適用することにより、読みやすくなります。

bdr.run_on_nodes() 出力のフォーマット#

PostgresのJSON式を使用すると、出力を関心のある列のみに減らすことができます。次のコマンドは、前の例と機能的に同等ですが、結果としてノードと応答のみをリストします。

select q->>node_name as node, q->>response as response FROM jsonb_array_elements(bdr.run_on_nodes(ARRAY[node-one,node-three], VACUUM FULL foo)) q;
__OUTPUT__
         node     |         response
- -----------------+------------------------------
 node-one         | {"command_status": "VACUUM"}
 node-three       | {"command_status": "VACUUM"}

エラーが発生した場合、command_status フィールドはerrorに設定されます。追加のerror_message 値が応答に含まれます。例

select q->>node_name as node, q->>response as response FROM jsonb_array_elements(bdr.run_on_nodes(ARRAY[node-one,node-three], VACUUM FULL fool)) q;
__OUTPUT__
    node          |                                         response
- -----------------+--------------------------------------------------------------------------------------------
 node-one         | {"error_message": "ERROR:  relation \"fool\" does not exist\n", "command_status": "ERROR"}
 node-three       | {"error_message": "ERROR:  relation \"fool\" does not exist\n", "command_status": "ERROR"}
(2 rows)

メンテナンス用のファンクションの定義#

一度に1つのノードにメンテナンスコマンドを定期的に発行する場合は、作業を簡素化するファンクションを定義できます。

create or replace function runmaint(nodename varchar, command varchar) returns TABLE(node text,response jsonb) as $$
begin
return query
select (q->>node_name)::text, (q->response) from jsonb_array_elements(bdr.run_on_nodes(ARRAY [nodename], command)) as q;
end;
$$ language plpgsql;

このファンクションは、ノード名とコマンドを取得し、そのノードでコマンドを実行し、この相互作用に示すような結果を結果ます。

select runmaint(node-one,VACUUM FULL foo);
__OUTPUT__
                    runmaint
- ------------------------------------------------------
 (node-one,"{""command_status"": ""VACUUM""}")

select * from を使用して、レスポンスを分割できます。

select * from runmaint(node-one,VACUUM FULL foo);
__OUTPUT__
    node          |         response
- -----------------+------------------------------
 node-one         | {"command_status": "VACUUM"}
(1 row)