web-dev-qa-db-ja.com

Postgresqlの論理レプリケーションを使用して、サブスクライバが追いついていることをどのようにして知ることができますか?

Postgresqlには、新しい論理複製システムの進行状況を監視するための興味深い監視ツールがいくつかありますが、私はそれらを本当に理解していません。私が知っている2つのツールは次のとおりです。

pg_stat_replication

そしてそれは兄弟です:

pg_stat_subscription

私はこれらのドキュメントを読みましたが、レプリカが実際に同期されているかどうかを確認する方法は示されていません。誰か説明できますか?

2
mlissner

昨年、postgres 10でレプリケーションを使用しましたが、ドキュメントが十分に明確ではないため、プロセスを監視する方法を理解するのに同じ問題がありました。とにかく、監視が行われているかどうかを確認する例を挙げましょう。

PUBLISHER側では、確認できることがいくつかあります。
-pg_catalog.pg_publication;
-pg_catalog.pg_publication_tables;
-pg_current_wal_lsn();

T_1とt_2の2つのテーブルを持つパブリケーション「test_publication」を作成します。必要な前提条件(ユーザー、ロールなど)については説明しません。

test_logical_replication=# create publication test_publication for table t_1, t_2;  
CREATE PUBLICATION  
test_logical_replication=# select * from pg_catalog.pg_publication;  
pubname      | pubowner | puballtables | pubinsert | pubupdate | pubdelete  
-----------------+----------+--------------+-----------+-----------+-----------  
test_publication |       10 | f            | t         | t         | t  
(1 row) 

test_logical_replication=# select * from pg_publication_tables;    
    pubname      | schemaname | tablename  
    ------------------+------------+-----------  
     test_publication | public     | t_1  
     test_publication | public     | t_2  
    (2 rows)  

加入者側:

test_logical_replication_subscriber=# create subscription test_subscription CONNECTION 'dbname=test_logical_replication Host=XXX user=repuser' PUBLICATION test_publication;  
NOTICE:  created replication slot "test_subscription" on publisher   
CREATE SUBSCRIPTION 

興味深い情報は、pg_catalog.pg_stat_subscriptionテーブルにあります。
ここで重要な列は次のとおりです:
-received_lsn:受信した最後の先読みログの場所
-last_msg_send_time:PUBLISHERから受信した最後のメッセージの送信時刻
-last_msg_receipt_time:PUBLISHERから受信した最後のメッセージの受信時刻
-latest_end_lsn:PUBLISHERに報告された最後の先行書き込みログの場所
-latest_end_time:PUBLISHERに報告された最後の先行書き込みログの場所の時刻

何が起こっているのかを把握するには、これらの列をチェックする必要があります。
最初に、2つのデータベースが同期しているかどうかを確認します。

パブリッシャー側:

test_logical_replication=> select pg_current_wal_lsn();  
 pg_current_wal_lsn  
--------------------  
 0/8EB83768     << this is the location on Wal file where we are now, before starting new insert  

SUBSCRIBERで、現時点で2つのデータベースが同期していることを確認できます。
パブリッシャーの関数pg_current_wal_lsn()によって返された値が、サブスクライバーのreceived_lsnおよびlatest_end_lsn列の値と一致します:

test_logical_replication_subscriber=# select received_lsn, latest_end_lsn from pg_catalog.pg_stat_subscription;  

received_lsn    | latest_end_lsn  
----------------+------------------     
 0/8EB83768     | 0/8EB83768        

テーブルt_1に4000行を追加して、PUBLISHERで何が発生するかを確認します。

test_logical_replication=> insert into t_1 select id+1, txt||'--BB' from t_1;  
INSERT 0 4000  


test_logical_replication=> select pg_current_wal_lsn();  
 pg_current_wal_lsn
--------------------
 0/8EC4B9D0             <<< this value in increasing
(1 row)

test_logical_replication=> select pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/8EC4DE78             <<< this value in increasing
(1 row)

test_logical_replication=> select pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/8EC4DEB0             <<< this value in increasing
(1 row) 

test_logical_replication=> select pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/8EC4DEB0            <<< same value, wal sending has finished
(1 row)  

sUBSCRIBERでのレプリケーション中にpg_catalog.pg_stat_subscriptionの値がどのように変化するかを見てみましょう。

test_logical_replication_subscriber=# select received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time from pg_catalog.pg_stat_subscription;
 received_lsn |      last_msg_send_time       |    last_msg_receipt_time     | latest_end_lsn |        latest_end_time  
--------------+-------------------------------+------------------------------+----------------+-------------------------------
 0/8EC4B9D0   | 2018-12-17 11:39:56.014564+01 | 2018-12-17 11:39:56.07322+01 | 0/8EC4B9D0     | 2018-12-17 11:39:56.014564+01
(1 row)  

test_logical_replication_subscriber=# select received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time from pg_catalog.pg_stat_subscription;
 received_lsn |      last_msg_send_time       |     last_msg_receipt_time     | latest_end_lsn |        latest_end_time
--------------+-------------------------------+-------------------------------+----------------+-------------------------------
 0/8EC4BA08   | 2018-12-17 11:39:56.737101+01 | 2018-12-17 11:39:56.736303+01 | 0/8EC4BA08     | 2018-12-17 11:39:56.737101+01  
(1 row)  

test_logical_replication_subscriber=# select received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time from pg_catalog.pg_stat_subscription;
 received_lsn |      last_msg_send_time       |     last_msg_receipt_time     | latest_end_lsn |        latest_end_time
--------------+-------------------------------+-------------------------------+----------------+-------------------------------
 0/8EC4DE78   | 2018-12-17 11:40:04.184765+01 | 2018-12-17 11:40:04.183937+01 | 0/8EC4DE78     | 2018-12-17 11:40:04.184765+01
(1 row)  

 test_logical_replication_subscriber=# select received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time from pg_catalog.pg_stat_subscription;
 received_lsn |      last_msg_send_time       |   last_msg_receipt_time    | latest_end_lsn |        latest_end_time
--------------+-------------------------------+----------------------------+----------------+-------------------------------
 0/8EC4DEB0   | 2018-12-17 11:40:17.153797+01 | 2018-12-17 11:40:17.153+01 | 0/8EC4DEB0     | 2018-12-17 11:40:17.153797+01
(1 row)   

ご覧のように、サブスクライバーでは、4つの列がWALがパブリッシャーからどのように到着し、どのように適用されるかを示しています。列last_msg_send_timeとlast_msg_receipt_timeの時間の違いにより、パブリッシャーとサブスクライバー間のラグに関する情報が得られます。
この場合、2つのサーバーは同じデータセンターの異なるサブネット上にあります。私が使用した2つのサーバーはテストサーバーであり、それらの間の同期は完全ではないことを考慮に入れてください。 (サブスクライバーサーバーには、NTPサーバーがまったく構成されていません)。

この助けを願っています。よろしく
MarcoP。

2
MarcoP

パブリッシャー(プロバイダー)側で、このSQL(バージョン> = PG10の場合)の出力をチェックして、ラグを取得します。

select   pid, client_addr, state, sync_state,  
         pg_wal_lsn_diff(sent_lsn, write_lsn) as write_lag,  
         pg_wal_lsn_diff(sent_lsn, flush_lsn) as flush_lag,  
         pg_wal_lsn_diff(sent_lsn, replay_lsn) as replay_lag
from pg_stat_replication;

また、pglogical拡張機能を使用している場合は、テーブルのレプリケーションステータスを確認できます。次のクエリがサブスクライバー側で(exp。整合性の問題のために)問題のあるテーブルを返す場合:

SELECT sub.sub_name, sync_kind, sync_relname, sync_status 
  FROM pglogical.local_sync_status stat 
  JOIN pglogical.subscription sub ON sub.sub_id = stat.sync_subid 
 WHERE sync_status!='r'
1
derkan

レプリカが同期されるかどうかは、ナノ秒からナノ秒に変わる可能性があるため、一般的に、それを確認した時点で正確であることがわかっているものに対して、明確な答えを得る方法はありません。 (synchronized_commitを十分に高い値に設定して、常に同期していることがわかるようにする以外)

0
jjanes

SELECT subscription_name, status FROM pglogical.show_subscription_status();

ここで、statuscurrentです

更新:これは実際には(現在のバージョンの?)pglogicalでも機能しません。私はそれをブログの投稿で読みましたが、それは実際の振る舞いではないと思います。見る:

0
John Bachir