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.
- Utilisation de l'utilitaire de ligne de commande Slonik avec le script de préambule REPAIR CONFIG ou
- 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.