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

「警告:sl_tableとpg_classの間に不一致が見つかりました。」 Slony-Iで

    警告:sl_tableとpg_classの間に不一致が見つかりました。 SlonikコマンドのREPAIRCONFIGは、これを修正するのに役立つ場合があります。
    2014-04-26 07:32:54 PDT FATAL slon_node_health_check()がfalseを返しました–致命的なヘルスの問題です!
    REPAIRCONFIGはこの問題を修正するのに役立つ場合があります

    Slonyがノード内の複製テーブルのpg_class.oidとsl_table.tabreloidの不一致を観察した場合、この警告メッセージがログに表示され、複製が即座に停止します。なぜなら、アーキテクチャによって、slonyは、設定時にpg_class.oidからキャプチャされたカタログ内のすべての複製オブジェクトのOID情報を保持しているからです。

    この場合、pg_class.oid!=sl_table.tabreloid?

    ほとんどの場合、ノードはオブジェクトOIDを変更することにより、pg_dump/pg_restoreを使用してその場所を移動しました。

    上記の警告メッセージを模倣するために、いくつかのテーブルで同じクラスター[5432]上の2つのデータベース間で2ノードレプリケーションセットアップを使用しました。 (Slonyレプリケーションのセットアップ方法についてはこちらを参照してください)。オブジェクト「dtest」の1つに対するスレーブノード(デモデータベース)の現在のOID情報は次のとおりです。

    demo=# select oid,relfilenode,relname from pg_class where relname='dtest';
    oid | relfilenode | relname
    -------+-------------+---------
    26119 | 26119 | detest
    (1 row)
    demo=# select tab_id,tab_reloid,tab_relname from _rf.sl_table where tab_relname='dtest';
    tab_id | tab_reloid | tab_relname
    --------+------------+-------------
    2 | 26119 | dtest
    (1 row)

    わかりました。sl_table.tabreloidのslonyカタログに保存されている「dtest」OID26119(Slonyスキーマ_rf)。同じデモデータベースの論理バックアップと復元を行って、以下のようにオブジェクトOIDを変更します:(この時点でSlonプロセスが停止していることを忘れないでください)

    -bash-4.1$ pg_dump -Fc -p 5432 -U postgres demo >/tmp/demo93.dmp
    -bash-4.1$ psql -c "alter database demo rename to demo_bk;"
    -bash-4.1$ psql -c "create database demo;"
    -bash-4.1$ pg_restore -Fc -p 5432 -U postgres -d demo /tmp/demo93.dmp
    -bash-4.1$ psql -c "select oid,relfilenode,relname from pg_class where relname='dtest';"
    oid | relfilenode | relname
    -------+-------------+---------
    26640 | 26640 | dtest
    (1 row)
    -bash-4.1$ psql -c "select tab_id,tab_reloid,tab_relname from _rf.sl_table where tab_relname='dtest';"
    tab_id | tab_reloid | tab_relname
    --------+------------+-------------
    2 | 26119 | dtest
    (1 row)

    現在、'dtest'のpg_class.oidは26640に変更されていますが、sl_table.tab_reloidは古いOID 26119を反映しています。この段階でslonプロセスを開始すると、クエリpg_class.oid =sl_table.tabreloid。誤った結果を返すと、修正されるまで先に進みません。検証のために関数slon_node_health_check()を明示的に呼び出すこともできます:

    demo=# select _rf.slon_node_health_check();
    WARNING: table [id,nsp,name]=[1,a,public] - sl_table does not match pg_class/pg_namespace
    WARNING: table [id,nsp,name]=[2,dtest,public] - sl_table does not match pg_class/pg_namespace
    WARNING: table [id,nsp,name]=[3,movepage,public] - sl_table does not match pg_class/pg_namespace
    WARNING: Mismatch found between sl_table and pg_class. Slonik command REPAIR CONFIG may be useful to rectify this.
    slon_node_health_check
    ------------------------
    f
    (1 row)

    これは2つの方法で修正できます。

    1. プリアンブルスクリプトREPAIRCONFIGまたは
    2. でSlonikコマンドラインユーティリティを使用する
    3. psqlターミナル内でSlonyカタログ関数updatereloid()を使用します。

    方法1: 以下のようにプリアンブルスクリプトを作成し、slonikコマンドで実行します。参考までに、2番目の方法を使用します。

    demo=# o /tmp/repair_conf.slonik
    demo=# select 'REPAIR CONFIG ( SET ID = '||set_id||', EVENT NODE = 1 );' FROM _rf.sl_set;
    demo=# o

    Add nodes information at the beginning of the file "/tmp/repair_conf.slonik"

    cluster name = rf;
    node 1 admin conninfo = 'host=localhost dbname=postgres user=postgres port=5432 password=postgres';
    node 2 admin conninfo = 'host=localhost dbname=demo user=postgres port=5432 password=postgres';

    REPAIR CONFIG ( SET ID = 1, EVENT NODE = 2 );
    REPAIR CONFIG ( SET ID = 2, EVENT NODE = 2 );
    REPAIR CONFIG ( SET ID = 3, EVENT NODE = 2 );

    -bash-4.1$ slonik /tmp/repair_conf.slonik

    方法2: テーブルセットIDとノード情報を関数に渡します:

    demo=# select _rf.updatereloid(tab_set,2) from _rf.sl_table ;   
    updatereloid
    --------------
    1
    1
    1
    (3 rows)

    かっこいい、pg_classと_slonycatalog.sl_tableからスレーブノード(デモデータベース)のOID情報を確認しましょう

    -bash-4.1$  psql -d demo -c "select oid,relfilenode,relname from pg_class where relname='dtest';"
    oid | relfilenode | relname
    -------+-------------+---------
    26119 | 26119 | dtest
    (1 row)

    -bash-4.1$ psql -d demo -c "select tab_id,tab_reloid,tab_relname from _rf.sl_table where tab_relname='dtest';"
    tab_id | tab_reloid | tab_relname
    --------+------------+-------------
    2 | 26119 | dtest
    (1 row)

    更新後、slonyは問題なく同期を開始します。
    Slony-Iチームに感謝します。


    1. Oracleテーブル変更モニター

    2. MySQLで文字セットをlatin1からUTF8に変更する方法

    3. SQL Server2019の新機能

    4. SQLite Group By