PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

"AVERTISSEMENT :incompatibilité détectée entre sl_table et pg_class." dans Slony-I

AVERTISSEMENT :incompatibilité trouvée entre sl_table et pg_class. La commande Slonik REPAIR CONFIG peut être utile pour rectifier cela.
2014-04-26 07:32:54 PDT FATAL slon_node_health_check() a retourné false - problème de santé fatal !
REPAIR CONFIG peut être utile pour rectifier ce problème

Vous voyez ce message d'AVERTISSEMENT dans les journaux et l'arrêt immédiat de la réplication, si Slony a observé une non-concordance entre pg_class.oid et sl_table.tabreloid d'une table répliquée dans un nœud. Parce que, par architecture, slony contient toutes les informations OID des objets répliqués dans ses catalogues capturés au moment de la configuration à partir de pg_class.oid.

Dans quel cas pg_class.oid !=sl_table.tabreloid ?

Dans la plupart des cas, un nœud a déplacé sa place à l'aide de pg_dump/pg_restore en provoquant le changement d'OID d'objets.

Pour imiter le message d'avertissement ci-dessus, j'ai utilisé une configuration de réplication à deux nœuds entre deux bases de données sur le même cluster [5432] pour quelques tables. (Reportez-vous ici pour savoir comment configurer la réplication Slony). Voici les informations OID actuelles sur le nœud esclave (base de données de démonstration) pour l'un des objets "dtest" :

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)

Ok, ‘dtest’ OID 26119 stocké dans le catalogue slony dans sl_table.tabreloid.(schéma Slony _rf). Prenez la sauvegarde et la restauration logiques de la même base de données de démonstration simplement pour changer l'OID de l'objet comme ci-dessous :(rappelez-vous, les processus Slon sont arrêtés à ce moment)

-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)

Maintenant, pg_class.oid de 'dtest' est passé à 26640 alors que sl_table.tab_reloid reflète toujours l'ancien OID 26119. À ce stade, si nous démarrons le processus slon, il s'arrête essentiellement avec un message d'avertissement en cas de non-concordance d'OID en exécutant une requête pg_class.oid =sl_table.tabreloid. En renvoyant un faux résultat, il n'avancera pas tant qu'il n'aura pas été corrigé. On peut aussi appeler explicitement la fonction slon_node_health_check() pour vérification :

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)

Nous pouvons résoudre ce problème de deux manières.

  1. Utilisation de l'utilitaire de ligne de commande Slonik avec le script de préambule REPAIR CONFIG ou
  2. Utilisation de la fonction de catalogue Slony updatereloid() dans le terminal psql.

Méthode 1 : Créez un script de préambule comme ci-dessous et exécutez-le avec la commande slonik. J'utiliserais la deuxième méthode, c'est juste pour référence.

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

Méthode 2 : Transmettez l'identifiant de l'ensemble de tables et les informations de nœud à une fonction :

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

Cool, vérifions maintenant les informations OID sur le nœud esclave (base de données de démonstration) à partir de pg_class et _slonycatalog.sl_table

-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)

Après la mise à jour, slony commencera à se synchroniser sans aucun problème.
Merci à l'équipe Slony-I.