Monitoring through SQL
======================

EDB Postgres
Distributedは、分散の性質に固有のいくつかのモニタリングおよび統計ビューを提供します。標準のPostgresモニタリングは、
EDB Postgres分散をモニタリングするのにも役立ちます。

モニタリングの概要
------------------

PGDグループは、複数のサーバーで構成されており、多くの場合ノードと呼ばれます。すべてのノードを監視して、グループ全体の状態を確認します。

bdr_monitorロールは、 ``bdr.monitor``
ファンクションを実行して、3つのレベルのいずれかを使用してPGDの状態の評価を提供できます。

- ``OK`` — 通常、緑色で表示されます。

- ``WARNING`` — 通常、黄色で表示されます。

- ``CRITICAL`` — 通常、赤で表示されます。

- ``UNKNOWN`` — 認識されない状況の場合、多くの場合赤で表示されます。

PGDは、さまざまな内部メトリックの瞬間的な状態を表示する動的なカタログビューも提供します。また、ユーザーが要求した構成のデフォルトと構成の変更を保存するメタデータカタログも提供します。これらのビューとテーブルの一部は、
bdr_monitorまたはbdr_read_all_statsからアクセスできますが、一部には、より高いセキュリティ要件が必要なユーザーまたは内部情報が含まれています。

PGDを使用すると、各ノードを個別に監視したり、単一のノードへのアクセスでグループ全体を監視したりできます。各ノードを個別に監視する場合は、各ノードに接続し、監視要求を発行します。これらの要求は他のノードを呼び出してグループレベルの情報セットをアセンブルするため、単一のノードからグループをモニタする場合は、
``bdr.group`` で始まるビューを使用します。

bdr_superuserによって\ ``bdr.run_on_all_nodes()``
ファンクションへのアクセスが付与されている場合、すべてのノードに独自の呼び出しを行うことができます。

監視ノードの参加と削除
----------------------

デフォルトでは、ノード管理機能はjoinまたはpart操作が完了するまで待機します。それぞれの\ ``wait_for_completion``
ファンクション引数を使用して、待機をオフにできます。待機がオフになっている場合、joinまたはpartオペレーションが終了したときを確認するには、
``bdr.node_summary`` および\ ``bdr.event_summary``
を使用して間接的にノードの状態を確認します。

ヘルパーファンクション\ ``bdr.wait_for_join_completion()``
は、呼び出されると、すべての未処理のノード結合操作領域が完了するまでPostgreSQLセッションを一時停止します。

この例は、 ``bdr.node_summary`` からの\ ``SELECT``
クエリーの出力を示しています。これは、2つのノードがアクティブで、別の1つが参加していることを示します。

::


   #  SELECT node_name, interface_connstr, peer_state_name,

   #      node_seq_id, node_local_dbname

   #  FROM bdr.node_summary;

   - [ RECORD 1 ]-----+-----------------------------------------
   node_name         | node1
   interface_connstr | host=localhost dbname=postgres port=7432
   peer_state_name   | ACTIVE
   node_seq_id       | 1
   node_local_dbname | postgres
   - [ RECORD 2 ]-----+-----------------------------------------
   node_name         | node2
   interface_connstr | host=localhost dbname=postgres port=7433
   peer_state_name   | ACTIVE
   node_seq_id       | 2
   node_local_dbname | postgres
   - [ RECORD 3 ]-----+-----------------------------------------
   node_name         | node3
   interface_connstr | host=localhost dbname=postgres port=7434
   peer_state_name   | JOINING
   node_seq_id       | 3
   node_local_dbname | postgres

また、テーブル `bdr.node_catchup_info <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_catchup_info>`_ は、ノードへの参加または分離に関連する可能性のあるキャッチアップ状態に関する情報を提供します。

ノードが分離されると、クラスター内の一部のノードがその分離したノードからすべてのデータを受信しない場合があります。したがって、ノードを分離すると、そのデータを既に受信し、転送できるノードから一時的なスロットが作成されます。

``catchup_state`` は、次のいずれかです。

::

   10 = setup
   20 = start
   30 = catchup
   40 = done

マネージャーワーカーの監視
--------------------------

マネージャーワーカーは、他のすべてのワーカーの管理を含む多くのバックグラウンドタスクを担当します。そのため、特に行き詰まっているように見える場合、それが何をしているのかを知ることが重要です。

したがって、
`bdr.stat_worker <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_worker>`_ ビューは、マネージャーワーカーを含むPGDワーカーのワーカーごとの統計を提供します。マネージャーワーカーがスタックしないように、実行中の現在のタスクは、“pgd
manager:”の接頭辞が付いている\ ``query`` フィールドで報告されます。

マネージャーワーカーの\ ``worker_backend_state``
フィールドは、マネージャーがアイドル状態かビジー状態かを報告します。

モニタリングルーティング
------------------------

ルーティングは、シームレスなアプリケーションエクスペリエンスと競合の回避を保証するためのPGDの重要な部分です。ルーティングの変更は、障害の検出を含めて、迅速に発生する必要があります。同時に、中断はできるだけ少なくしたいと考えています。また、サポートされているユースケースで、適切なロードバランシングを保証したいと考えています。

これらをすべて監視することは、問題に気づき、問題をデバッグし、より最適な構成を通知するために重要です。したがって、ルーティングに関連する監視統計には、2つの主なビューがあります。

- `bdr.stat_routing_state <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_routing_state>`_ 
  接続マネージャーを使用した接続ルーティングの状態をモニタリングするための使用
  接続のルーティングに使用します。

- Raftリーダーの観点からのルーティング候補ノードに関する情報については `bdr.stat_routing_candidate_state <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_routing_candidate_state>`_ 
  ビューは他のノードでは空です。

レプリケーションピアのモニタリング
----------------------------------

レプリケーションアクティビティの監視には、2つのメインビューを使用します。

- `bdr.node_slots <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_slots>`_  送信レプリケーションを監視するため

- `bdr.subscription_summary <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrsubscription_summary>`_  着信レプリケーションを監視するため

標準のPostgreSQLレプリケーション監視ビューを照会することにより、
``bdr.node_slots`` が提供する情報のほとんどを取得することもできます
 
`pg_catalog.pg_stat_replication <https://www.postgresql.org/docs/current/static/monitoring-stats.html#PG-STAT-REPLICATION-VIEW>`_ 

および 
`pg_catalog.pg_replication_slots <https://www.postgresql.org/docs/current/view-pg-replication-slots.html>`_  。

各ノードには1つのPGDグループスロットがあります。これらのスロットには接続してはならず、アクティブとしてマークされることはほとんどありません。これは正常であり、何かがダウンまたは切断されていることを意味するものではありません。ノード管理の :ref:`Replication slots created by PGD <Replication slots created by PGD>` を参照してください。

送信レプリケーションの監視
^^^^^^^^^^^^^^^^^^^^^^^^^^

送信レプリケーションアクティビティの監視に別のビューを使用できます。

- `bdr.node_replication_rates <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_replication_rates>`_  送信レプリケーションを監視するため

`bdr.node_replication_rates <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_replication_rates>`_ ビューは、送信レプリケーションアクティビティの全体像と、特にピアノードのキャッチアップ推定を提供します。

::


   #  SELECT * FROM bdr.node_replication_rates;

   - [ RECORD 1 ]----+-----------
   peer_node_id     | 112898766
   target_name      | node1
   sent_lsn         | 0/28AF99C8
   replay_lsn       | 0/28AF99C8
   replay_lag       | 00:00:00
   replay_lag_bytes | 0
   replay_lag_size  | 0 bytes
   apply_rate       | 822
   catchup_interval | 00:00:00
   - [ RECORD 2 ]----+-----------
   peer_node_id     | 312494765
   target_name      | node3
   sent_lsn         | 0/28AF99C8
   replay_lsn       | 0/28AF99C8
   replay_lag       | 00:00:00
   replay_lag_bytes | 0
   replay_lag_size  | 0 bytes
   apply_rate       | 853
   catchup_interval | 00:00:00

``apply_rate``
は、1秒あたりのバイト数のレートを参照します。これは、ピアがローカルノードからデータを消費している速度です。ノードがクラスターに再接続したときの\ ``replay_lag``
は、すぐにゼロに設定されます。この情報は将来のリリースで修正される予定です。回避策として、ピアノードがローカルノードデータに追いつくまでに必要な時間を参照する\ ``catchup_interval``
列を使用することをお勧めします。他のフィールドは、
`bdr.node_slots <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_slots>`_ から利用できます。

ビュー。

管理者は、ローカルノードからの送信レプリケーションについて `bdr.node_slots <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrnode_slots>`_ を照会できます。これは、現在のノードで知られているグループ内の他のすべてのノードのレプリケーションステータスと、現在のノードでPGDによって作成された追加のレプリケーションスロットに関する情報を表示します。

::


   #  SELECT node_group_name, target_dbname, target_name, slot_name, active_pid,

   #      catalog_xmin, client_addr, sent_lsn, replay_lsn, replay_lag,

   #      replay_lag_bytes, replay_lag_size

   #  FROM bdr.node_slots;

   - [ RECORD 1 ]---+----------------------------
   node_group_name | bdrgroup
   target_dbname   | postgres
   target_name     | node3
   slot_name       | bdr_postgres_bdrgroup_node3
   active_pid      | 15089
   catalog_xmin    | 691
   client_addr     | 127.0.0.1
   sent_lsn        | 0/23F7B70
   replay_lsn      | 0/23F7B70
   replay_lag      | [NULL]
   replay_lag_bytes| 120
   replay_lag_size | 120 bytes
   - [ RECORD 2 ]---+----------------------------
   node_group_name | bdrgroup
   target_dbname   | postgres
   target_name     | node2
   slot_name       | bdr_postgres_bdrgroup_node2
   active_pid      | 15031
   catalog_xmin    | 691
   client_addr     | 127.0.0.1
   sent_lsn        | 0/23F7B70
   replay_lsn      | 0/23F7B70
   replay_lag      | [NULL]
   replay_lag_bytes| 84211
   replay_lag_size | 82 kB

PGDはメッシュネットワークであるため、クラスター内の遅延の完全なビューを取得するには、参加しているすべてのノードでこのクエリを実行する必要があります。

``replay_lag_bytes``
は、ローカルサーバーの現在のWAL書き込み位置と、ピアノードによって再生確認された最後の位置である\ ``replay_lsn``
間のWAL位置の差を報告します。 ``replay_lag_size``
は、同じの人が判読可能な形式です。通常、WALには、レプリケートされないが\ ``replay_lag_bytes``
でカウントされる大量の書き込みが含まれることを理解することが重要です。

- ``VACUUM`` アクティビティ

- インデックスの変更

- 同じノード上の他のデータベースに関連付けられた書き込み

- レプリケーションセットの一部ではないテーブルの書き込み

したがって、ここで報告されるバイト単位の遅延は、ピアノードを最新の状態にするためにワイヤで複製する必要があるデータの量ではなく、処理する必要があるサーバーサイドのWALの量のみです。

同様に、 ``replay_lag``
は、ピアノードが追いつくまでに要した時間、または現在位置から\ ``bdr.node_slots``
が照会された時点の書き込み位置まで再生に要した時間を表すものではありません。ピアが最新のコミットを確認したときと現在の実測時間との間の遅延を測定します。この列は、ノードが再接続した直後にゼロに設定されるため、
``replay_lag_bytes`` と\ ``replay_lag_size``
または\ ``bdr.node_replication_rates`` の\ ``catchup_interval``
をモニタすることをお勧めします。

論理レプリケーションがトランザクションをストリーミングしている間、バイトと時間の両方の遅延は進行しません。コミットがレプリケートされた場合にのみ変更されます。したがって、遅延は「のこぎり波」の傾向があり、トランザクションがストリーミングされると上昇し、ピアノードがコミット、フラッシュ、確認を送信すると再び低下します。報告されたLSNは、同様の理由で、スムーズに進むのではなく、「階段」を位置づけています。

レプリケーションが切断されている場合 ``active`` = ``'f'`` 、
``active_pid`` 列は\ ``NULL`` 、 ``client_addr``
およびアクティブな接続でのみ意味をなすその他のフィールドと同様に、
``NULL`` です。 ``state`` フィールドは\ ``'disconnected'`` です。
``_lsn``
フィールドは、クライアントが再生および保存したことが確認されている最後の位置であるため、\ ``confirmed_flush_lsn``
と同じです。 ``_lag``
フィールドは、クライアントで確認された最新のフラッシュから現在までの経過時間を示します。
``_lag_size`` および\ ``_lag_bytes`` フィールドは、
``confirmed_flush_lsn``
とローカルサーバーの現在のWAL挿入位置間の距離をレポートします。

..  Note::
   `restart_lsn` が他の`lsn` 列の後ろにあるのは通常です。これは、レプリケーションまたはピアノードの遅延に関する問題を示しているわけではありません。 `restart_lsn` は、PostgreSQLの内部論理デコードが中断された場合にWALを読み取る位置です。これは、通常、まだレプリケートおよびフラッシュされていない最も古いトランザクションの位置を反映します。非常に古い`restart_lsn` は、切断後のレプリケーションの再起動を遅くし、望ましいよりも多くのWALの保持を強制する場合がありますが、それ以外の場合は無害です。心配する場合は、非常に長時間実行されているトランザクションと忘れられた準備済みトランザクションを探してください。

着信レプリケーションの監視
^^^^^^^^^^^^^^^^^^^^^^^^^^

``bdr.subscription_summary``
ビューを照会することにより、受信レプリケーションサブスクリプションとも呼ばれますを高レベルでモニタできます。このクエリは、EDB
Postgres分散クラスター内の他のノードへの既知のサブスクリプションのリストとレプリケーションワーカーの状態を表示します。

::


   #  SELECT node_group_name, origin_name, sub_enabled, sub_slot_name,

   #      subscription_status

   #  FROM bdr.subscription_summary;

   - [ RECORD 1 ]-------+----------------------------
   node_group_name     | bdrgroup
   origin_name         | node2
   sub_enabled         | t
   sub_slot_name       | bdr_postgres_bdrgroup_node1
   subscription_status | replicating
   - [ RECORD 2 ]-------+----------------------------
   node_group_name     | bdrgroup
   origin_name         | node3
   sub_enabled         | t
   sub_slot_name       | bdr_postgres_bdrgroup_node1
   subscription_status | replicating

`bdr.stat_subscription <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_subscription>`_ を介してサブスクリプションの概要統計をモニタリングし、それぞれ
`bdr.stat_receiver <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_receiver>`_ および `bdr.stat_writer <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_writer>`_ を使用してサブスクリプションレプリケーションレシーバーとサブスクリプションレプリケーションライターをモニタリングすることにより、サブスクリプションをさらにモニタできます。

LCRを使用したWAL送信者のモニタリング
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:ref:`Decoding worker <Decoding worker>` が有効になっている場合、ファンクション 
`bdr.wal_sender_stats() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions/#bdrwal_sender_stats>`_ 
を使用して、各WALセンダーの現在の論理変更レコードLCRファイルに関する情報をモニタできます。例

::

   postgres=# SELECT * FROM bdr.wal_sender_stats();
      pid   | is_using_lcr |       decoder_slot_name       |              lcr_file_name
   - --------+--------------+-------------------------------+------------------------------------------
    2059904 | f            |                               |
    2059909 | t            | bdr_postgres_bdrgroup_decoder | 0000000000000000000000140000000000000000
    2059916 | t            | bdr_postgres_bdrgroup_decoder | 0000000000000000000000140000000000000000
   (3 rows)

``is_using_lcr`` が\ ``FALSE`` の場合、\ ``decoder_slot_name``
/``lcr_file_name`` は\ ``NULL``
です。これは、デコードワーカーが有効になっていない場合、またはWAL送信者が
:ref:`Logical standby nodes <Logical standby nodes>`  を提供している場合に当てはまります。

また、ファンクション
 
`bdr.get_decoding_worker_stat() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions/#bdrget_decoding_worker_stat>`_ を使用して、デコードワーカーに関する情報をモニタできます。例

::

   postgres=# SELECT * FROM bdr.get_decoding_worker_stat();
      pid   | decoded_upto_lsn | waiting | waiting_for_lsn
   - --------+------------------+---------+-----------------
    1153091 | 0/1E5EEE8        | t       | 0/1E5EF00
   (1 row)

PGDレプリケーションワーカーのモニタリング
-----------------------------------------

すべてのPGDワーカーは、
 
`pg_stat_activity <https://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-ACTIVITY-VIEW>`_ と同じ列と情報コンテンツがあるシステムビュー\ ``bdr.stat_activity``
に表示されます。したがって、このビューは、PGDシステムの状態に関する次の洞察を提供します。

- 待機の理由がPGDに関連している場合、wait_event列に強化された情報があります。

- ライタプロセスがDDLを実行している場合、またはマネージャーワーカーがアクティブな場合を除き、
  PGDワーカーの\ ``query`` 列は空白です。この場合、 ``query``
  列のエントリには「\ ``pgd manager:`` 」の接頭辞が付けられます。

``bdr.workers`` ビューには、 ``bdr.stat_activity``
からは使用できないPGDワーカー固有の詳細が表示されます。

``bdr.event_summary``
ビューは、作業の続行に問題があるワーカーによって報告された最後のエラーがある場合を表示します。この情報は永続的なため、エラーの存在だけでなく、エラーの時間を記録することが重要です。ほとんどのエラーは一時的なもので、
PGDワーカーは失敗した操作を再試行します。

PGDライターのモニタリング
-------------------------

別のシステムビュー\ ``bdr.writers``
は、ライタアクティビティを監視します。このビューには、ライタワーカーの現在のステータスのみが表示されます。それには以下が含まれます

- ``sub_name`` ライタが属しているサブスクリプションを識別する

- ライタプロセスの\ ``pid``

- ``streaming_allowed``
  ライタが進行中のストリーミングトランザクションの適用をサポートしているかどうかを知るため

- ``is_streaming``
  ライタが現在ストリーミングトランザクションを適用しているかどうかを知るため

- ``commit_queue_position`` コミットキュー内のライタの位置を確認する

PGDは、オリジンで発生したのと同じコミット順序に従って、コミット順序を尊重します。並列ライターの場合、複数のライターが異なるトランザクションを同時に適用する場合があります。
``commit_queue_position`` は、コミットする順序を示します。値\ ``0``
は、ライタが最初にコミットすることを意味します。値\ ``-1``
は、コミット位置がまだ不明であることを意味します。これは、ストリーミングトランザクション、またはライタが現在トランザクションを適用していない場合に発生します。

コミットスコープのモニタリング
------------------------------

コミットスコープは、耐久性と一貫性の構成フレームワークです。そのため、それらはトランザクションのパフォーマンスに影響を与えるため、それらに関する統計を取得することが重要です。さらに、障害シナリオでは、コミットスコープの構成が原因でトランザクションがスタックしているように見える場合があるため、どのコミットスコープが使用されているか、何を待機しているかなどに関する洞察が必要です。

したがって、これらの2つのビューは、コミットスコープに関する関連統計を示します。

- `bdr.stat_commit_scope <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_commit_scope>`_  デグレードイベントカウンター ``ndegrades``
  、\ ``nconfig_degrades`` や最後の構成状態変更のタイムスタンプ
  ``last_state_change_time`` を含む各コミットスコープの累積統計。

- `bdr.stat_commit_scope_state <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_commit_scope_state>`_ 
  バックエンドプロセスによるコミットスコープの現在の使用に関する情報。

デグレードイベントのモニタリングの詳細については、
:ref:`機能低下イベントの監視 <機能低下イベントの監視>` を参照してください。

グローバルロックの監視
----------------------

グローバルロックは、現在DDLレプリケーションにのみ使用されていますが、
PGDグループ全体に存在する重量ロックです。

現在、2種類のグローバルロックがあります。

- DDLロック、データベース内の一時的なものではない永続的なオブジェクトつまりテーブルに対するすべてのDDL操作をシリアル化するために使用されます

- DMLリレーションロック、リレーション定義を変更するDDL操作中にリレーションへの書き込みをロックアウトするために使用されます

DDL操作のタイプと\ ``bdr.ddl_locking``
設定の値に応じて、同じトランザクションに一方または両方のエントリータイプを作成できます。

ローカルノードで保持されているグローバルロックは、 `bdr.global_locks <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrglobal_locks>`_ ビューに表示されます。
このビューには、ロックのタイプが表示されます。リレーションロックの場合、ロックされている関係、ロックを保持しているPIDローカルの場合、およびロックがグローバルに付与されたかどうかを示します。グローバルアドバイザリロックの場合、
``lock_type`` 列は\ ``GLOBAL_LOCK_ADVISORY`` を示し、 ``relation``
列は、ロックが取得されるアドバイザリキーを示します。

この例は、 ``bdr.ddl_locking = 'all'`` を使用して\ ``ALTER TABLE``
ステートメントを実行中の\ ``bdr.global_locks`` の出力を示しています。

::


   #  SELECT lock_type, relation, pid FROM bdr.global_locks;

   - [ RECORD 1 ]--------------
   lock_type | GLOBAL_LOCK_DDL
   relation  | [NULL]
   pid       | 15534
   - [ RECORD 2 ]--------------
   lock_type | GLOBAL_LOCK_DML
   relation  | someschema.sometable
   pid       | 15534

ロックタイミング情報を含むすべてのフィールドの詳細については、
`Catalogs <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/>`_ を参照してください。

競合のモニタリング
------------------

レプリケーション
:ref:`bdr_read_all_conflicts <bdr_read_all_conflicts>` は、複数のノードが相互作用できる方法で同じ行に影響を与える変更を行う場合に発生する可能性があります。
PGDシステムをモニタして競合を特定し、可能であればアプリケーションを変更して競合を排除するか、競合の頻度を減らします。

デフォルトでは、すべての競合は\ ``bdr.conflict_history``
ログに記録されます。このログには、競合するデータの完全な詳細が含まれているため、行は行レベルのセキュリティで保護され、レプリケートテーブルの所有者にのみ表示されます。所有者は競合を予想し、それらを分析して、存在する場合、どれが解決すべき問題と考えられるかを確認する必要があります。

モニタリングには、ユーザーデータを含まない `bdr.conflict_history_summary <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrconflict_history_summary>`_ 
を使用します。この例は、効率的なクエリプランを使用して、その日に発生した競合の数をカウントするクエリを示しています。

.. code:: sql

   SELECT count(*)
   FROM bdr.conflict_history_summary
   WHERE local_time > date_trunc(day, current_timestamp)
     AND local_time < date_trunc(day, current_timestamp + 1 day);

統計を適用する
--------------

PGDは、サブスクリプションごととテーブルごとの両方で、レプリケーションの適用に関する統計を収集します。

2つのモニタリングビューが存在します。サブスクリプション統計の場合は `bdr.stat_subscription <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrstat_subscription>`_ 、リレーション統計の場合は `bdr.stat_relation <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrstat_relation>`_ です。これらのビューは両方とも次を提供します。

- レプリケートされたINSERT / UPDATE / DELETE / TRUNCATEの数

- ブロックアクセスとキャッシュヒット率

- 読み取り/書き込みの合計I/O時間

- ファイルにストリーミングされた進行中のトランザクションの数

- ライターにストリーミングされる進行中のトランザクションの数

- コミット/中止された進行中のストリーミングトランザクションの数

リレーションのみの場合、 `bdr.stat_relation <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrstat_relation>`_ には次のものも含まれます。

- リレーションのレプリケーションの処理に費やされた合計時間

- リレーションのみのロックがある場合を取得するまでの合計ロック待機時間

サブスクリプションの場合のみ、 `bdr.stat_subscription <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrstat_subscription>`_ には以下が含まれます。

- サブスクリプションに対してレプリケートされたCOMMIT/ DDLの数

- このサブスクリプションがアップストリームに接続した回数

これらの統計の追跡は、それぞれPGD GUC
 
`bdr.track_subscription_apply <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/pgd-settings#bdrtrack_subscription_apply>`_ および `bdr.track_relation_apply <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/pgd-settings#bdrtrack_relation_apply>`_ によって制御されます。

次に、これらの出力例を示します。

.. code:: sql


   #  SELECT sub_name, nconnect, ninsert, ncommit, nupdate, ndelete, ntruncate, nddl

   FROM bdr.stat_subscription;
   - [ RECORD 1 ]----------------------------------
   sub_name  | bdr_regression_bdrgroup_node1_node2
   nconnect  | 3
   ninsert   | 10
   ncommit   | 5
   nupdate   | 0
   ndelete   | 0
   ntruncate | 0
   nddl      | 2

この場合、サブスクリプションは上流に3回接続し、10行を挿入し、5つのトランザクション内で2つのDDLコマンドを実行しました。

ファンクション
`bdr.reset_subscription_stats <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions-internal#bdrreset_subscription_stats>`_ および `bdr.reset_relation_stats <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions-internal#bdrreset_relation_stats>`_ を使用して、これらのビューの統計カウンターをゼロにリセットできます。

PGDは、それぞれ `bdr.stat_receiver <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_receiver>`_  および `bdr.stat_writer <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_writer>`_ 
を使用して、各サブスクリプションのサブスクリプションレプリケーションレシーバーとサブスクリプションレプリケーションライターに関する統計も監視します。

標準のPostgreSQL統計ビュー
--------------------------

テーブルとインデックスの使用状況に関する統計は、通常、ダウンストリームマスターによって更新されます。これは、
 
`autovacuum <https://www.postgresql.org/docs/current/static/routine-vacuuming.html>`_ の正しい機能のために重要です。ダウンストリームマスターにローカル書き込みがなく、統計がリセットされていない場合、これらの2つのビューは、アップストリームとダウンストリームで対応する結果を表示します。

- ``pg_stat_user_tables``

- ``pg_statio_user_tables``

..  Note::
   上流のテーブル統計がダウンストリームのテーブル統計と*同様*であることを必ずしも期待しているわけではありません。私たちはそれらが同じ量だけ*変更*されることを期待しています。統計が100万の挿入と100万の更新を示すテーブルの例を考えます。新しいノードがPGDグループに参加すると、新しいノードの同じテーブルの統計には、1Mの挿入とゼロの更新が示されます。ただし、その瞬間から、一方の側ですべての変更がもう一方の側にレプリケートされるため、上流と下流のテーブル統計は同じ量だけ変更されます。

インデックスは変更を適用するために使用されるため、ダウンストリーム側の識別インデックスは、非識別インデックスよりも\ ``UPDATE``
および\ ``DELETE``
を実行するワークロードで頻繁に使用される場合があります。

ビルトインインデックスモニタリングビューは次のとおりです。

- ``pg_stat_user_indexes``

- ``pg_statio_user_indexes``

これらのビューはすべて、 
`PostgreSQL documentation on the statistics views <http://www.postgresql.org/docs/current/static/monitoring-stats.html#MONITORING-STATS-VIEWS-TABLE>`_ で詳細に説明されています。

PGDバージョンのモニタリング
---------------------------

PGDでは、同じクラスター内のノード全体で異なるPostgresバージョンと異なるBDR拡張バージョンを実行できます。この機能は、アップグレードに役立ちます。

ビュー `bdr.group_versions_details <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrgroup_versions_details>`_ は、ファンクション 
`bdr.run_on_all_nodes() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrrun_on_all_nodes>`_ を使用して、すべてのノードからPostgresおよびBDR拡張バージョンを同時に取得します。例

.. code:: sql

   pgddb=# SELECT node_name, postgres_version, bdr_version
           FROM bdr.group_versions_details;
    node_name | postgres_version | bdr_version
   - ----------+------------------+-------------
    node1     | 15.2.0           | 5.0.0
    node2     | 15.2.0           | 5.0.0

推奨されるセットアップは、すべてのノードでできるだけ早く同じ最新のバージョンを実行するようにすることです。クラスターは、
BDR拡張機能のさまざまなバージョンを長時間実行しないことをお勧めします。

モニタリングのために、次のアラートレベルをお勧めします。

- status = UNKNOWN、message =このノードはPGDグループの一部ではありません

- status = OK、message
  =すべてのノードが同じPGDバージョンを実行しています

- status = WARNING、message
  =アクセスできないノードが少なくとも1つあります

- status = WARNING、message
  =他のノードと比較して、異なるPGDバージョンを実行しているノードがあります

説明した動作は、
 
`bdr.monitor_group_versions() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrmonitor_group_versions>`_ ファンクションに実装されています。このファンクションは、ビュー
``bdr.group_version_details``
から返されたPGDバージョン情報を使用して、クラスター全体のバージョンチェックを提供します。例

.. code:: sql

   pgddb=# SELECT * FROM bdr.monitor_group_versions();
    status |                message
   - -------+-----------------------------------------
    OK     | All nodes are running same BDR versions

Monitoring Raftコンセンサス
---------------------------

Raftコンセンサスは、常にクラスター全体で動作している必要があります。
Raftコンセンサスが機能せずにEDB
Postgres分散クラスターを実行した場合の影響は次のとおりです。

- PGDデータ変更のレプリケーションは、引き続き正常に動作する場合があります。

- グローバルDDL/DMLロックは機能しません。

- Gallocシーケンスは、最終的にチャンクを使い果たします。

- Eager Replicationが機能しない。

- クラスターメンテナンス操作ノード参加、部分ノード、プロモートスタンバイは引き続き許可されますが、完了しない代わりにハングする場合があります。

- PGDノード間でノードのステータスが正しく同期されない場合があります。

- PGDグループレプリケーションスロットはLSNを進歩させないため、ディスク上にWALファイルを保持します。

ビュー `bdr.group_raft_details <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrgroup_raft_details>`_ は、ファンクション 
`bdr.run_on_all_nodes() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrrun_on_all_nodes>`_ および 
`bdr.get_raft_status() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrget_raft_status>`_ を使用して、すべてのノードから同時にRaftコンセンサスステータスを取得します。例

.. code:: sql

   pgddb=# SELECT node_id, node_name, state, leader_id
   FROM bdr.group_raft_details;
     node_id   | node_name | node_group_name |     state     | leader_id
   - -----------+-----------+-----------------+---------------+------------
    1148549230 | node1     | top_group       | RAFT_LEADER   | 1148549230
    3367056606 | node2     | top_group       | RAFT_FOLLOWER | 1148549230

これらの条件がすべて満たされる場合、Raftコンセンサスは正常に動作します。

- 有効な状態\ ``RAFT_LEADER`` または\ ``RAFT_FOLLOWER``
  がすべてのノードで定義されています。

- ノードのうちの1つだけが\ ``RAFT_LEADER`` です。

- ``leader_id`` はすべての行で同じであり、\ ``state = RAFT_LEADER``
  が存在する行の\ ``node_id`` と一致する必要があります。

時々、Raftコンセンサスは新しい選挙を開始して、新しい\ ``RAFT_LEADER``
を定義します。選挙中に、\ ``RAFT_LEADER``
が存在せず、一部のノードが自分自身を\ ``RAFT_CANDIDATE``
と見なす中間状況が発生する場合があります。選挙全体には\ ``bdr.raft_global_election_timeout``
より長くかかることはありませんデフォルトでは6秒に設定されています。上記のクエリーが選挙中の状況を結果た場合、
``bdr.raft_global_election_timeout``
を待って、クエリーを再度実行します。
``bdr.raft_global_election_timeout``
が経過した後、リストされた条件の一部がまだ満たされていない場合、Raftコンセンサスは機能していません。

Raftコンセンサスは、単一のノードでのみ正常に動作していない可能性があります。たとえば、ノードの1つが現在のリーダーを認識せず、自分自身を\ ``RAFT_CANDIDATE``
と見なします。この場合、次のことを確認することが重要です。

- すべてのPGDノードは、レギュラー接続とレプリケーション接続の両方を介して相互にアクセスできますチェックファイル
  ``pg_hba.conf`` 。

- PGDバージョンはすべてのノードで同じです。

- ``bdr.raft_global_election_timeout`` はすべてのノードで同じです。

場合によっては、特にノードが地理的に離れている場合、またはネットワーク遅延が高い場合、
``bdr.raft_global_election_timeout``
のデフォルト値6秒では十分でない場合があります。すべてが正しいことを確認した後でもRaftコンセンサスがまだ機能していない場合は、すべてのノードで\ ``bdr.raft_global_election_timeout``
を30秒に増加することを検討します。

Raftコンセンサスがクラスター操作タスクにどのような影響を与えるか、またRaftコンセンサスがグループスロットを前進させることに直接責任があるため、モニタリングアラートレベルは次のように定義されます。

- status = UNKNOWN、message =このノードはPGDグループの一部ではありません

- status=OK、message=Raftコンセンサスは正常に動作しています

- status = WARNING、message
  =アクセスできないノードが少なくとも1つあります

- status = WARNING、 message =
  RAFT_CANDIDATEとしてノードがあります、選択が進行中の可能性があります

- status = WARNING、message =
  RAFT_LEADERがありません、選挙が進行中の可能性があります

- status=CRITICAL、message=Raftコンセンサスには単一のノードがあります

- status = CRITICAL、message = RAFT_CANDIDATEとしてノードがありますが、
  RAFT_LEADERが定義されています

- status=CRITICAL、message=RAFT_LEADERとして設定されたノードとは異なるリーダーをフォローしているノードがあります。

説明した動作はファンクション 
`bdr.monitor_group_raft() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrmonitor_group_raft>`_ 
に実装されます。これは、ビュー
`bdr.group_raft_details <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrgroup_raft_details>`_ から返されたRaftコンセンサスステータス情報を使用します

クラスター全体のRaftチェックを提供します。例

.. code:: sql

   pgddb=# SELECT * FROM bdr.monitor_group_raft();
   node_group_name | status |               message
   - ---------------|--------+-------------------------------------
   mygroup          | OK     | Raft Consensus is working correctly

Raftコンセンサスの状態をより詳細に与えることができるさらに2つのビューは、ローカルノードでのRaftコンセンサスの状態を提供する `bdr.stat_raft_state <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_raft_state>`_ と、Raftリーダー上のときのビューを提供する `bdr.stat_raft_followers_state <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible/#bdrstat_raft_followers_state>`_ です。他のノード)そのRaftリーダーのフォロワーの状態に関するもの。

レプリケーションスロットの監視
------------------------------

各PGDノードは以下を保持します。

- アクティブなPGDピアごとに1つのレプリケーションスロット

- 1つのグループレプリケーションスロット

例

.. code:: sql

   pgddb=# SELECT slot_name, database, active, confirmed_flush_lsn
   FROM pg_replication_slots ORDER BY slot_name;
           slot_name         | database | active | confirmed_flush_lsn
   - -------------------------+----------+--------+---------------------
    bdr_pgddb_bdrgroup       | pgddb    | f      | 0/3110A08
    bdr_pgddb_bdrgroup_node2 | pgddb    | t      | 0/31F4670
    bdr_pgddb_bdrgroup_node3 | pgddb    | t      | 0/31F4670
    bdr_pgddb_bdrgroup_node4 | pgddb    | t      | 0/31F4670

ピアスロット名は\ ``bdr_<DATABASE>_<GROUP>_<PEER>`` 規則に従いますが、
PGDグループスロット名は\ ``bdr_<DATABASE>_<GROUP>``
規則に従います。ファンクション 
`bdr.local_group_slot_name() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrlocal_group_slot_name>`_ 
を使用してグループスロットにアクセスできます。

ピアレプリケーションスロットは、すべてのノードで常にアクティブである必要があります。ピアレプリケーションスロットがアクティブでない場合、それは次のいずれかを意味する可能性があります。

- 対応するピアはシャットダウンしているか、アクセスできません。

- PGDレプリケーションが壊れています。

``ERROR`` または\ ``FATAL``
のログファイルをgrepし、すべてのノードで\ ``bdr.event_summary``
を確認します。根本的な原因は、たとえば、ノードの1つでDDLレプリケーションを無効にして、互換性のないDDLが実行されたことが考えられます。

ただし、
PGDグループレプリケーションスロットは、ほとんどの場合非アクティブです。他のすべてのピアが対応するトランザクションを既に消費している場合、
PGDはこのスロットを維持し、そのLSNを進めます。したがって、グループスロットのステータスを監視する必要はありません。

ファンクション 
`bdr.monitor_local_replslots() <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/functions#bdrmonitor_local_replslots>`_ は、すべてのPGDノードレプリケーションスロットが予想通りに動作しているかどうかの概要を提供します。この概要は、
:ref:`Optimizing subscriber-only groups <Optimizing subscriber-only groups>` が有効になっているときにPGDクラスターでサブスクライバ専用グループリーダーとして動作しているサブスクライバ専用ノードでも利用できます。例

.. code:: sql

   pgddb=# SELECT * FROM bdr.monitor_local_replslots();
    status |                    message
   - -------+-------------------------------------------------
    OK     | All BDR replication slots are working correctly

次のステータスの概要のいずれかが返されます。

.. csv-table::
  :header: Status,Message
  :widths: 10,30
  :align: left
  :class: longtable

  UNKNOWN,This node is not part of any BDR group
  OK,All BDR replication slots are working correctly
  OK,This node is part of a subscriber-only group
  CRITICAL,There is at least 1 BDR replication slot which is inactive
  CRITICAL,There is at least 1 BDR replication slot which is missing

トランザクションのCOMMITの監視
------------------------------

デフォルトでは、
PGDトランザクションはローカルノードにのみコミットされます。その場合、トランザクションの\ ``COMMIT``
は迅速に処理されます。

PGDの :ref:`コミットスコープへの移行 <コミットスコープへの移行>` 機能は、特定のクエリーの耐久性、一貫性、パフォーマンスのバランスを可能にするさまざまな同期トランザクションコミットスコープを提供します。
`bdr.stat_activity <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/catalogs-visible#bdrstat_activity>`_ カタログを調べることにより、これらのトランザクションをモニタできます。トランザクションがコミットされると、プロセスはさまざまな\ ``wait_event``
状態を報告します。このモニタリングは、進行中のトランザクションのみをカバーし、履歴タイミング情報は提供しません。
