PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

„WARNUNG:Diskrepanz zwischen sl_table und pg_class gefunden.“ in Slony-I

WARNUNG:Diskrepanz zwischen sl_table und pg_class gefunden. Der Slonik-Befehl REPAIR CONFIG kann hilfreich sein, um dies zu beheben.
2014-04-26 07:32:54 PDT FATAL slon_node_health_check() gab false zurück – schwerwiegendes Gesundheitsproblem!
REPAIR CONFIG kann hilfreich sein, um dieses Problem zu beheben

Sie sehen diese WARNUNG-Meldung in Protokollen und einen sofortigen Stopp der Replikation, wenn Slony eine Nichtübereinstimmung von pg_class.oid und sl_table.tabreloid einer replizierenden Tabelle in einem Knoten beobachtet hat. Denn slony hält architekturbedingt alle OID-Informationen zu replizierenden Objekten in seinen Katalogen, die zur Konfigurationszeit von pg_class.oid erfasst wurden.

In welchem ​​Fall pg_class.oid !=sl_table.tabreloid ?

In den meisten Fällen hat ein Knoten seinen Platz verschoben, indem er pg_dump/pg_restore verwendet hat, indem er bewirkt hat, dass sich die OID von Objekten ändert.

Um die obige WARNUNG-Nachricht nachzuahmen, habe ich für einige Tabellen eine Zwei-Knoten-Replikation zwischen zwei Datenbanken auf demselben Cluster [5432] eingerichtet. (Lesen Sie hier, wie Sie die Slony-Replikation einrichten). Hier sind die aktuellen OID-Informationen zum Slave-Knoten (Demo-Datenbank) für eines der Objekte „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 gespeichert im Slony-Katalog in sl_table.tabreloid. (Slony-Schema _rf). Führen Sie die logische Sicherung und Wiederherstellung derselben Demo-Datenbank durch, um einfach die Objekt-OID wie folgt zu ändern:(Denken Sie daran, dass der Slon-Prozess in diesem Moment gestoppt wird)

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

Jetzt hat sich pg_class.oid von 'dtest' in 26640 geändert, während sl_table.tab_reloid immer noch die alte OID 26119 widerspiegelt. Wenn wir zu diesem Zeitpunkt den slon-Prozess starten, stoppt er im Wesentlichen mit einer WARNUNG bei Nichtübereinstimmung der OID, indem eine Abfrage pg_class.oid =ausgeführt wird sl_table.tabreloid. Bei der Rückgabe eines falschen Ergebnisses wird es nicht weitergehen, bis es behoben ist. Wir können die Funktion slon_node_health_check() auch explizit zur Überprüfung aufrufen :

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)

Wir können dies auf zwei Arten beheben.

  1. Verwenden des Befehlszeilenprogramms Slonik mit dem Präambelskript REPAIR CONFIG oder
  2. Verwenden der Slony-Katalogfunktion updatereloid() innerhalb des psql-Terminals.

Methode 1: Erstellen Sie das Präambelskript wie unten und führen Sie es mit dem Befehl slonik aus. Ich würde die zweite Methode verwenden, sie dient nur als Referenz.

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

Methode 2: Übergeben Sie die Tabellensatz-ID und die Knoteninformationen an eine Funktion:

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

Cool, überprüfen wir jetzt die OID-Informationen auf dem Slave-Knoten (Demo-Datenbank) von pg_class und _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)

Nach dem Update beginnt Slony ohne Probleme mit der Synchronisierung.
Danke an das Slony-I-Team.