pg_comparator – Online in der Cloud

Dies ist der Befehl pg_comparator, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME/FUNKTION


pg_comparator – effizienter Vergleich und Synchronisierung von Tabelleninhalten

ZUSAMMENFASSUNG


pg_comparator [Optionen als --help --Möglichkeit --Mann] Verbindung1 Verbindung2

BESCHREIBUNG


Dieses Skript führt einen netzwerk- und zeiteffizienten Vergleich oder eine Synchronisierung von zwei durch
evtl. große Tische drin PostgreSQL, MySQL or SQLite Datenbanken, um eingefügte,
aktualisierte oder gelöschte Tupel zwischen diesen Tabellen. Der Algorithmus ist effizient, insbesondere wenn
die erwarteten Unterschiede sind relativ gering.

Die Implementierung ist recht allgemein gehalten: Mehrspaltige Schlüssel (aber es muss einen Schlüssel geben!), Nein
Annahme anderer Datentypen, dass sie in Text umgewandelt werden können, kann eine Teilmenge von Spalten sein
Wird für den Vergleich, die Behandlung von NULL-Werten usw. verwendet.

Dieses Skript konzentriert sich auf den Vergleichsalgorithmus, daher die vielen Optionen. Die Tatsache, dass es
kann irgendetwas Nützliches tun, wie z. B. überprüfen, ob ein Replikationstool tatsächlich Replikationen durchführt
Ihrer Daten oder etwa das Synchronisieren von Tabellen ist lediglich ein Nebeneffekt.

OPTIONAL


Mit den Optionen können Sie Hilfe anfordern oder einige interne Parameter anpassen. Kurzer Ein-Buchstabe
Es sind auch Optionen verfügbar, normalerweise mit dem ersten Buchstaben des Optionsnamens.

„--aggregate=(sum|xor)“ oder „-a (sum|xor)“
Aggregationsfunktion, die auch für Zusammenfassungen verwendet werden kann xor or Summe. Es muss funktionieren
das Ergebnis der Prüfsummenfunktion. Für PostgreSQL und SQLite gilt: xor Aggregat
muss geladen werden. Bei der Verwendung liegt ein signiertes/nicht signiertes Problem beim Schlüssel-Hash vor xor
zum Vergleichen von Tabellen auf MySQL oder SQLite vs. PostgreSQL. Wir bieten ein neues „ISUM“
Aggregat für SQLite, da sowohl „SUM“ als auch „TOTAL“ eine inkompatible Verarbeitung durchführen
Ganzzahlüberläufe.

Standardeinstellung ist Summe weil es standardmäßig verfügbar ist und im gemischten Modus funktioniert.

„--ask-pass“
Interaktiv nach Passwörtern fragen. Siehe auch die Option „--env-pass“ unten.

Standardmäßig wird nicht nach Passwörtern gefragt.

„--asynchronous“ oder „-A“, „--no-asynchronous“ oder „-X“
Ob asynchrone Abfragen ausgeführt werden sollen. Dies sorgt jedoch für eine gewisse Parallelität der beiden
Verbindungen werden pro Abfrage mehr oder weniger synchronisiert.

Standardmäßig werden asynchrone Abfragen verwendet, um eine gewisse Parallelität zu ermöglichen.

„--checksum-computation=(create|insert)“ oder „--cc=…“
So erstellen Sie die Prüfsummentabelle. Verwenden erstellen um ein „CREATE ... AS SELECT ...“ zu verwenden
abfragen, bzw einfügen um eine „CREATE ...; INSERT ... SELECT ...“-Abfrage zu verwenden. Der erstere wird
erfordern eine zusätzliche Zählung, um die Tabellengröße zu erhalten, sodass es am Ende zwei sind
Anfragen sowieso. Es gibt ein Problem mit der Schriftgröße einfügen Strategie auf MySQL, die
Die kumulierte Länge der Schlüsselzeichenfolge muss unter 64 Byte liegen.

Standardeinstellung ist erstellen weil es immer für beide Datenbanken funktioniert.

„--checksum-function=fun“ oder „--cf=fun“ oder „-c fun“
Auch die Prüfsummenfunktion kann verwendet werden ck, fnv or md5. Für PostgreSQL, MySQL und SQLite die
vorausgesetzt ck und fnv Prüfsummenfunktionen müssen in die Zieldatenbanken geladen werden.
Die Wahl md5 ist ebenfalls nicht kostenlos: Die bereitgestellten Cast-Funktionen müssen geladen werden
in die Zieldatenbanken und die Berechnung ist teurer.

Standardeinstellung ist ck, was schnell ist, insbesondere wenn der Vorgang CPU-gebunden ist und die
Die Bandbreite ist einigermaßen hoch.

„--checksum-size=n“ oder „--check-size=n“ oder „--cs=n“ oder „-zn“
Tupel-Prüfsummengröße, muss sein 2, 4 or 8 Bytes. Die Größe der Schlüsselprüfsumme beträgt immer 4 Byte
lang.

Standardeinstellung ist 8, sodass die Falsch-Negativ-Wahrscheinlichkeit sehr gering ist. Es sollte nein geben
Grund, das zu ändern.

"--Aufräumen"
Löschen Sie vorher Prüfsummen- und Übersichtstabellen. Nützlich nach einem Lauf mit „--no-temp“ und
„--no-clear“, wird normalerweise zum Debuggen verwendet.

Standardmäßig wird es nicht gelöscht, da es nicht benötigt wird.

"--klar"
Löschen Sie Prüfsummen- und Übersichtstabellen nach der Berechnung explizit. Beachten Sie, dass dies der Fall ist
werden standardmäßig implizit gelöscht, wenn die Verbindung geschlossen wird, da sie temporär sind, siehe
Option „-(-no)-temporär“. Diese Option ist zum Debuggen nützlich.

Standardeinstellung ist nicht die Prüfsummen- und Übersichtstabellen explizit zu löschen, da dies nicht der Fall ist
Installation!

„--debug“ oder „-d“
Debug-Modus einstellen. Wiederholen Sie diesen Vorgang für höhere Debug-Level. Siehe auch „--verbose“. Hüten Sie sich davor
Einige Sicherheitsvorkehrungen zu Optionseinstellungen werden beim Debuggen übersprungen, um Tests zu ermöglichen
unter anderen Bedingungen.

Standardmäßig wird nicht im Debug-Modus ausgeführt.

"--env-pass='var'"
Nehmen Sie das Passwort aus den Umgebungsvariablen „var1“, „var2“ oder „var“ für Verbindung eins,
zwei oder beide. Dies wird versucht, bevor interaktiv abgefragt wird, ob auch „--ask-pass“ gesetzt ist.

Standardmäßig wird nicht nach Passwörtern aus Umgebungsvariablen gesucht.

„--expect n“ oder „-en“
Gesamtzahl der zu erwartenden Unterschiede (Aktualisierungen, Löschungen und Einfügungen). Diese Option ist
Wird nur für Nicht-Regressionstests verwendet. Siehe Abschnitt TESTS.

„--folding-factor=7“ oder „-f 7“
Faltfaktor: log2 der Anzahl der in jeder Phase gruppierten Zeilen, beginnend
aus den Blättern, sodass in der ersten Runde immer möglichst viele Datensätze gruppiert werden. Der
Eine Zweierpotenz ermöglicht die Verwendung maskierter Berechnungen. Der Mindestwert von 1 erstellt a
binärer Baum.

Der Standardfaltfaktor log2 ist 7, also Größe 128 Falten. Dieser Standardwert wurde gewählt
nach einigen grundlegenden Tests an mittelgroßen Gehäusen mit mittlerer oder niedriger Bandbreite. Werte aus
4 bis 8 sollten für die meisten Einstellungen eine vernünftige Wahl sein.

„--help“ oder „-h“
Kurzhilfe anzeigen.

„--key-checksum='kcs‘“ oder „--kcs=…“
Verwenden Sie das Schlüsselprüfsummenattribut dieses Namens, das bereits in den Tabellen verfügbar sein muss
vergleichen. Diese Option erfordert auch die Option „--tuple-checksum“. Siehe auch die
Im Abschnitt BEISPIELE weiter unten erfahren Sie, wie Sie einen Prüfsummenauslöser festlegen. Betrachten Sie „--use-key“
stattdessen, wenn Sie bereits einen einigermaßen verteilten ganzzahligen Primärschlüssel haben.

Standardmäßig werden sowohl Schlüssel- als auch Tupelprüfsummen im laufenden Betrieb erstellt.

„--lock“, „--no-lock“
Ob Tabellen gesperrt werden sollen. Wenn Sie die Option explizit festlegen, wird die Standardeinstellung für eine Richtung außer Kraft gesetzt
oder ein anderes. Für PostgreSQL erfordert diese Option „--transaction“, das aktiviert wird durch
default.

Der Standardwert hängt von der aktuellen Operation ab: Die Tabelle ist nicht verschlossen zum Vergleich,
aber es ist verschlossen für eine Synchronisation.

„--long-read-len=0“ oder „-L 0“
Legen Sie die maximale Größe für abgerufene binäre große Objekte fest. Nun, es scheint zumindest ignoriert zu werden
durch den PostgreSQL-Treiber.

Standardmäßig wird der vom Treiber festgelegte Standardwert beibehalten.

„--man“ oder „-m“
Handbuchseite interaktiv im Terminal anzeigen.

„--max-ratio=0.1“
Maximaler relativer Suchaufwand. Die Suche wird gestoppt, wenn die Anzahl der Ergebnisse beträgt
über diesem Schwellenwert, ausgedrückt im Verhältnis zur Tabellengröße. Verwenden Sie 2.0 ohne Begrenzung
(Alle Tupel wurden gelöscht und neue eingefügt).

Standardeinstellung ist 0.1, dh insgesamt sind 10 % Differenz zulässig, bevor aufgegeben wird.

„--max-report=n“
Maximaler absoluter Suchaufwand. Die Suche wird gestoppt, wenn die Anzahl der Unterschiede zu hoch ist
überschreitet diese Schwelle. Wenn festgelegt, wird die vorherige Option „--max-ratio“ ignoriert.
andernfalls wird der Aufwand mit dem Verhältnis berechnet, sobald die Tabellengröße bekannt ist.

Standardmäßig wird die maximale Anzahl der gemeldeten Unterschiede basierend auf berechnet
Option „--max-ratio“, wobei mindestens 100 Unterschiede zulässig sind.

„--max-levels=0“
Maximale Anzahl der verwendeten Ebenen. Ermöglicht das Abschneiden von Falten. 0 bedeutet keine Abschaltung.
Wenn Sie den Wert 1 festlegen, wird nur die Prüfsummentabelle ohne Zusammenfassungen verwendet. Ein Wert von
3 oder 4 wären sinnvoll, da die letzten Ebenen des Baums gut dafür geeignet sind
theoretische Komplexitätsformel, verbessern jedoch nicht die Leistung in der Praxis.

Standardeinstellung ist 0.

"--null='text'"
Umgang mit NULL-Werten. Entweder Hash- um alle Werte zu hashen, wobei NULL einen besonderen Wert hat
Hashwert, oder Text Dabei werden NULL-Werte durch die Zeichenfolge „NULL“ ersetzt.

Standardeinstellung ist Text weil es schneller ist.

„--option“ oder „-o“
Optionszusammenfassung anzeigen.

„--pg-copy=128“
Experimentelle Option zur Verwendung von COPY von PostgreSQL anstelle von INSERT/UPDATE, wenn
Synchronisieren, nach Blöcken der angegebenen Größe.

"--prefix='pgc_cmp'"
Namenspräfix, möglicherweise schemaqualifiziert, wird für generierte Vergleichstabellen verwendet von
indem man ihm Zahlen anhängt. Erwägen Sie, das Präfix zu ändern, wenn Sie mehrere davon erwarten
Vergleiche können gleichzeitig mit derselben Datenbank ausgeführt werden.

Der Standardwert ist „pgc_cmp“. Cheksum-Tabellen heißen „pgc_cmp_1_0“ und „pgc_cmp_2_0“ und
Übersichtstabellen werden durch Erhöhen der letzten Zahl benannt.

„--report“, „--no-report“
Melden Sie unterschiedliche Schlüssel an stdout, sobald sie gefunden werden.

Standardmäßig wird gemeldet.

„--separator='|'“ oder „-s '|'“
Trennzeichenfolge oder -zeichen, das beim Verketten von Schlüsselspalten für die Berechnung verwendet wird
Prüfsummen.

Standardmäßig ist die Pipe '|' Charakter.

„--size=n“
Nehmen Sie diesen Wert als Tabellengröße an. Es reicht aus, dass der Algorithmus funktioniert
Nun, diese Größe liegt in der Größenordnung der tatsächlichen Tabellengröße.

Standardmäßig werden die Tabellengrößen abgefragt, was übersprungen wird, wenn diese Option gesetzt ist.

"--source-1='DBI:...'", "--source-2='...'" oder "-1 '...'", "-2 '...'"
Übernehmen Sie die volle Kontrolle über die DBI-Datenquellenspezifikation und ignorieren Sie den Vergleich größtenteils
Authentifizierungsteil der Quell- oder Ziel-URLs. Man kann sich mit verbinden
„DBI:Pg:service=backup“, verwenden Sie einen alternativen Treiber und legen Sie alle vom System zugelassenen Optionen fest
Treiber... Siehe die Handbücher „DBD::Pg“ und „DBD:mysql“ für die verschiedenen möglichen Optionen
wird durch die DBI-Datenquellenspezifikation festgelegt. Allerdings ist der Datenbankserver angegeben
in der URL muss mit dieser Quellspezifikation übereinstimmen, damit die Abfragen
Die Syntax ist die richtige.

Standardmäßig wird auf die beiden URL-Argumente zurückgegriffen.

„--skip-inserts“, „--skip-updates“, „--skip-deletes“
Führen Sie diese Vorgänge beim Synchronisieren nicht aus.

Standardmäßig werden unter „--synchronize“ alle Vorgänge ausgeführt.

„--stats=(txt|csv)“
Zeigen Sie verschiedene Statistiken über den in diesem Format durchgeführten Vergleich an. Auch Option
„--stats-name“ gibt dem Test einen Namen, der zum Generieren von CSV-Dateien nützlich ist
automatisch verarbeitet.

Standardeinstellung ist nicht um Statistiken anzuzeigen, da hierfür zusätzliche Synchronisierungen erforderlich sind und
ist für den Benutzer nicht unbedingt interessant.

„--synchronize“ oder „-S“
Führen Sie tatsächlich Operationen aus, um die zweite Tabelle mit der ersten zu synchronisieren. Nun ja, nicht
Eigentlich ist es nur ein Trockenlauf. Es ist tatsächlich erledigt, wenn Sie „--do-it“ oder „-D“ hinzufügen. Speichern
Ihre Daten, bevor Sie so etwas versuchen!

Standardmäßig ist keine Synchronisierung vorgesehen.

„--temporär“, „--no-temporär“
Ob temporäre Tabellen verwendet werden sollen. Wenn Sie dies nicht tun, werden die Tabellen standardmäßig beibehalten
Ende, so dass sie manuell gelöscht werden müssen. Sehen Sie sich die Option „--clear“ an, um eine anzufordern
Aufräumen. Diese Option ist zum Debuggen nützlich.

Standardmäßig werden temporäre Tabellen verwendet, die automatisch gelöscht werden, wenn die
Verbindung ist geschlossen.

„--unlogged“, „--no-unlogged“
Verwenden Sie nicht protokollierte Tabellen zum Speichern von Prüfsummen. Diese Tabellen sind also nicht transaktional
kann die Sache etwas beschleunigen. Sie werden jedoch nicht automatisch bereinigt
Ende. Sehen Sie sich die Option „--clear“ an, um eine Bereinigung anzufordern.

Standardmäßig werden keine nicht protokollierten Tabellen verwendet.

„--threads“ oder „-T“, „--no-threads“ oder „-N“
Sehr EXPERIMENTELLE Funktion.

Versuchen Sie, Threads zu verwenden, um Berechnungen parallel durchzuführen, mit etwas Hokuspokus, weil
Das Perl-Thread-Modell funktioniert mit DBI nicht wirklich gut. Perl-Threads sind ziemlich schwer
und langsam, eigentlich eher wie kommunizierende Prozesse als leichte Threads.

Dies funktioniert mit PostgreSQL überhaupt NICHT. Teilweise funktioniert es auch mit MySQL
Preis für die Deaktivierung von „--transaction“.

Standardeinstellung ist nicht Threads zu verwenden, da dies nicht für alle Datenbanken funktioniert.

„--timeout n“
Timeout-Vergleich nach „n“ Sekunden.

Standardmäßig ist kein Timeout. Sei geduldig.

„--transaction“, „--no-transaction“
Ob der gesamte Algorithmus in einer einzigen Transaktion zusammengefasst werden soll.

Standardmäßig wird eine Wrapping-Transaktion verwendet, da dies sowohl schneller als auch sicherer zu sein scheint
tun Sie dies.

„--tuple-checksum='tcs‘“ oder „--tcs=…“
Verwenden Sie das Tupel-Prüfsummenattribut dieses Namens, das bereits im verfügbar sein muss
Tabellen zum Vergleichen. Für diese Option muss auch entweder „--use-key“ oder festgelegt werden
„--key-checksum=…“ oben. Die bereitgestellten Prüfsummenattribute dürfen nicht im enthalten sein
Listen von Schlüssel- und Wertspalten. Weitere Informationen zum Festlegen von a finden Sie auch im Abschnitt BEISPIELE weiter unten
Prüfsummentrigger.

Standardmäßig werden sowohl Schlüssel- als auch Tupelprüfsummen im laufenden Betrieb erstellt.

„--use-key“ oder „-u“
Ob der Wert des Schlüssels direkt verwendet werden soll, um Tupel auf Zweige zu verteilen. Der
Der Schlüssel muss einfach, ganzzahlig, nicht NULL und gleichmäßig verteilt sein. Wenn Sie eine haben
Wenn Sie den ganzzahligen Primärschlüssel angemessen verteilen, sollten Sie die Verwendung dieser Option in Betracht ziehen, um die Hälfte des Primärschlüssels zu vermeiden
Prüfsummentabellen-Hash-Berechnungen.

Standardmäßig wird der Schlüssel gehasht, um jeden Typ, jede Zusammensetzung und jede Verteilung zu verarbeiten.

„--use-null“, „--no-use-null“
Ob zur Vereinfachung die Information verwendet werden soll, dass eine Spalte als NOT NULL deklariert ist
Berechnungen, indem Aufrufe von COALESCE zur Verarbeitung von NULL-Werten vermieden werden.

Standardmäßig werden diese Informationen zum Preis der Abfrage von Tabellenmetadaten verwendet.

„--verbose“ oder „-v“
Seien Sie ausführlich darüber, was passiert. Je mehr Sie fragen, desto ausführlicher.

Standardmäßig ist es leise, damit mögliche Warnungen oder Fehler hervorgehoben werden.

„--version“ oder „-V“
Versionsinformationen anzeigen und beenden.

„--where=…“
SQL-Boolesche Bedingung für Tabellentupel für teilweisen Vergleich. Nützlich, um die zu reduzieren
Laden Sie, wenn Sie wissen, dass es in einigen Teilen Ihrer Daten erwartete Unterschiede gibt, sagen wir diese
Heute mit Zeitstempel versehen... Auf beiden Seiten wird die gleiche Bedingung übergeben, daher müssen beide Tabellen dies tun
ziemlich ähnlich sein, damit es funktioniert. Dies ist normalerweise der Fall.

Standardmäßig werden ganze Tabellen verglichen.

ARGUMENTE


Die beiden Argumente beschreiben Datenbankverbindungen mit der folgenden URL-ähnlichen Syntax:
Eckige Klammern kennzeichnen optionale Teile. Viele Teile sind standardmäßig optional. Das Minimum
Die syntaktisch korrekte Angabe ist „/“, aber das muss nicht unbedingt etwas bedeuten
sinnvoll.

[driver://][login[:pass]@][host][:port]/[base/[[schema.]table[?key[:cols]]]]

Siehe den Abschnitt BEISPIELE unten und auch die „--source-*“-Optionen oben.

Beachten Sie, dass einige von DBI-Treibern verwendete Standardwerte treiberspezifisch geändert werden können
Umgebungsvariablen, und dass DBI auch seine eigenen Standardwerte und Überschreibungen bereitstellt, na und
Was tatsächlich passiert, ist möglicherweise nicht immer klar. Standardwerte für die zweite URL sind meist
entnommen aus der ersten URL.

Fahrer
Zu verwendender Datenbanktreiber. Verwenden pgsql für PostgreSQL, mysql für MySQL, SQLite für SQLite.
Heterogene Datenbanken können zwar verglichen und synchronisiert werden, seien Sie jedoch vorsichtig
Typisierungs-, Codierungs- und Casting-Probleme können heterogene Vergleiche verhindern oder
Synchronisierungen zum Erfolg führen. Standard ist pgsql für die erste Verbindung und dasselbe wie
Erster für Zweiter.

Für SQLite wird der Authentifizierungsteil der URL (Login, Pass, Host, Port) erwartet
leer sein, daher sollte die vollständige URL wie folgt aussehen:

sqlite:///base.db/table?key,col:other,columns

Darüber hinaus wird die Umgebungsvariable PGC_SQLITE_LOAD_EXTENSION mit festgelegt
„:“-getrennte Shared-Object-Dateien laden diese in SQLite.

login
Melden Sie sich an, um eine Verbindung zur Datenbank herzustellen. Der Standardwert ist der Benutzername für die erste Verbindung.
und das Gleiche wie bei der ersten Verbindung für die zweite.

passieren
Passwort, das beim Herstellen einer Verbindung zur Datenbank verwendet werden soll. Beachten Sie, dass es keine gute Idee ist, ein zu setzen
Passwort als Befehlsargument. Der Standardwert ist „Keine“ für die erste Verbindung und die
Für die zweite Verbindung dasselbe Passwort wie bei der ersten Verbindung verwenden if Die Verbindung zielt auf die
Derselbe Host, Port und dasselbe Login. Siehe auch „--ask-pass“ und „--env-pass“
nach.

Gastgeber
Hostname oder IP für die Verbindung. Der Standardwert ist die leere Zeichenfolge, was bedeutet, dass eine Verbindung hergestellt wird
die Datenbank auf localhost mit einem UNIX-Socket.

port
TCP-IP-Port, mit dem eine Verbindung hergestellt werden soll. Der Standardwert ist 5432 für PostgreSQL und 3306 für MySQL.

Base
Datenbankkatalog, mit dem eine Verbindung hergestellt werden soll. Der Standardwert ist der Benutzername für die erste Verbindung. Standard ist
Gleiches gilt für die erste Verbindung für die zweite Verbindung. Stellen Sie für SQLite die Datenbankdatei bereit
Name. Der Pfad ist standardmäßig relativ, kann aber durch Voranstellen eines absolut gemacht werden
zusätzlich '/':

sqlite:////var/cache/sqlite/base.db/table?...

schema.table
Die möglicherweise schemaqualifizierte Tabelle, die für den Vergleich verwendet werden soll. Kein Standard für zuerst
Verbindung. Die Standardeinstellung ist dieselbe wie bei der ersten Verbindung für die zweite Verbindung.

Beachten Sie, dass MySQL dies nicht hat Schemata, aber seltsamerweise ihre Datenbank Konzept ist
genau wie ein Schema, also hat MySQL das wirklich nicht Datenbanken, obwohl es gibt
etwas mit diesem Namen. Ist das klar?

Tasten
Durch Kommas getrennte Liste der Schlüsselspalten. Der Standardwert ist zunächst der Tabellenprimärschlüssel
Verbindung. Die Standardeinstellung ist dieselbe wie bei der ersten Verbindung für die zweite Verbindung. Der Schlüssel
kann keine leer sein. Wenn Sie keine Möglichkeit haben, Ihre Tupel zu identifizieren, dann gibt es keine
Sinn bei der Suche nach Unterschieden.

Spalten
Durch Kommas getrennte Liste der zu vergleichenden Spalten. Kann leer sein. Standardmäßig sind alle Spalten außer
Tasten für die erste Verbindung. Die Standardeinstellung ist dieselbe wie bei der ersten Verbindung für die zweite Verbindung.
Beachten Sie, dass „...?key:“ eine leere Spalte bedeutet, während „...?key“ den Standardwert festlegt
Abfragen von Tabellenmetadaten.

Beispiele:


Vergleichen Sie die Tabellen Calvin und Hobbes in der Datenbankfamilie auf Localhost mit dem Schlüssel id und Spalten
c1 und c2:

./pg_comparator /family/calvin?id:c1,c2 /family/hobbes

Vergleichen Sie die Tabellen Calvin in der Standarddatenbank auf localhost und dieselbe Tabelle in der Standarddatenbank
Datenbank zu Sablons, mit Schlüssel id und Spalte frustrierten:

./pg_comparator localhost/family/calvin?id:data sablons/

Synchronisieren Sie die Tabelle „Benutzer“ in der Datenbank „Wikipedia“ von MySQL auf „Server1“ mit PostgreSQL auf
„server2“.

./pg_comparator -S -D --ask-pass
mysql://calvin@server1/wikipedia/user pgsql://hobbes@server2/

Für PostgreSQL können Sie vom Trigger verwaltete Schlüssel- und Tupelprüfsummen wie folgt hinzufügen:

-- TABLE Foo(id SERIAL PRIMARY KEY, data ... NOT NULL);
- Fügen Sie einen Schlüssel und Tupel-Prüfsummenattribute hinzu
-- die Schlüsselprüfsumme kann übersprungen werden, wenn Sie --use-key verwenden,
– wobei der Schlüssel eine einfache NOT NULL-Ganzzahl sein muss.
ALTER TABLE Foo
SPALTE HINZUFÜGEN key_cs INT4 NICHT NULL STANDARD 0,
SPALTE HINZUFÜGEN tup_cs INT8 NOT NULL DEFAULT 0;
-- Funktion zum Aktualisieren der Tupelprüfsumme
– Wenn einige Attribute NULL sein könnten, müssen sie zusammengeführt werden
FUNKTION ERSTELLEN foo_cs() Gibt TRIGGER ALS $$ ZURÜCK
START
- Schlüsselprüfsumme berechnen
NEW.key_cs = cksum4(NEW.id);
- Tupel-Prüfsumme berechnen
NEW.tup_cs = cksum8(NEW.id || '|' || NEW.data);
RÜCKGABE NEU;
ENDE; $$ SPRACHE plpgsql;
-- Setzen Sie den Trigger, um die Prüfsummenaktualisierungsfunktion aufzurufen
TRIGGER ERSTELLEN foo_cs_trigger
VOR DEM UPDATE ODER EINFÜGEN AUF Foo
FÜR JEDE ZEILE EXECUTE PROCEDURE foo_cs();
-- wenn die Tabelle Foo zunächst nicht leer ist,
– Aktualisieren Sie den Inhalt, um Prüfsummenberechnungen auszulösen
UPDATE Foo SET id=id;

Dann kann ein schneller Vergleich durchgeführt werden, der nicht die Berechnung der anfänglichen Prüfsummentabelle erfordert
angefragt mit:

./pg_comparator --tcs=tup_cs --kcs=key_cs
admin@server1/app/Foo?id:data hobbes@server2/

Da der Primärschlüssel eine einfache Ganzzahl ist, ist der key_cs könnte weggelassen werden und der Vergleich
könnte gestartet werden mit:

./pg_comparator --tcs=tup_cs --use-key
admin@server1/app/Foo?id:data hobbes@server2/

AUSGABE


Die Ausgabe des Befehls besteht aus Zeilen, die die gefundenen Unterschiede zwischen den beschreiben
zwei Tische. Sie werden in Form von Einfügungen, Aktualisierungen oder Löschungen und in Form von Tupeln ausgedrückt
Schlüssel.

AKTUALISIEREN k
Wesentliche k Tupel wird von Tabelle 1 auf Tabelle 2 aktualisiert. Es ist in beiden Tabellen mit vorhanden
verschiedene Werte.

INSERT k
Wesentliche k Tupel erscheint nicht in Tabelle 2, sondern nur in Tabelle 1. Es muss eingefügt werden
Tabelle 2, um es mit Tabelle 1 zu synchronisieren.

LÖSCHEN k
Wesentliche k Tupel erscheint in Tabelle 2, aber nicht in Tabelle 1. Es muss von 2 bis gelöscht werden
Synchronisieren Sie es mit Tabelle 1.

Bei Tupel-Prüfsummenkollisionen kann es zu falsch negativen Ergebnissen kommen. Wechseln
In solchen Fällen wäre eine Prüfsummenfunktion hilfreich. Siehe den Unterabschnitt ANALYSE.

ABHÄNGIGKEITEN


In der Datenbank werden drei Unterstützungsfunktionen benötigt:

1.
Die Funktion „COALESCE“ kümmert sich um NULL-Werte in Spalten.

2.
Zum Reduzieren und Verteilen von Schlüssel- und Spaltenwerten muss eine Prüfsummenfunktion verwendet werden. Es kann
mit der Option „--checksum“ geändert werden. Seine Größe kann mit ausgewählt werden
Option „--checksize“ (derzeit 2, 4 oder 8 Bytes). Die Prüfsummen erfordern auch Umwandlungen
in ganze Zahlen unterschiedlicher Größe umgewandelt.

Für PostgreSQL stehen passende Implementierungen zur Verfügung, die auf den Server geladen werden können
durch Verarbeitung von „share/contrib/pgc_checksum.sql“ und „share/contrib/pgc_casts.sql“. Neu
Prüfsummen und Casts sind auch für MySQL verfügbar, siehe „mysql_*.sql“. Eine ladbare
Die Implementierung geeigneter Prüfsummenfunktionen ist auch für SQLite verfügbar, siehe
„sqlite_checksum.*“.

Die „ck“-Prüfsumme basiert auf dem Jenkins-Hash ,
Dies beruht auf einfachen Additions-, Verschiebungs- und XOR-Integer-Operationen. Die Prüfsumme „fnv“ ist
inspiriert vom FNV-Hash (64 Bit 1a
Version), die xor- und mult-Integer-Operationen verwendet, obwohl ich auch etwas Shift hinzugefügt habe
und hinzufügen, um die Optimierung hoher Bits zu erleichtern.

3.
Eine Aggregatfunktion wird verwendet, um Prüfsummen für einen Bereich von Zeilen zusammenzufassen. Es muss
Arbeiten Sie mit dem Ergebnis der Prüfsummenfunktion. Es kann mit geändert werden
Option „--aggregate“.

Für PostgreSQL stehen geeignete Implementierungen eines Exklusiv- oder „xor“-Aggregats zur Verfügung
und kann durch Verarbeitung von „share/contrib/xor_aggregate.sql“ auf den Server geladen werden.

Die Datei „sqlite_checksum.*“ stellt auch „xor“- und „sum“-Aggregate für SQLite bereit
sind mit anderen Datenbanken kompatibel.

Darüber hinaus sind mehrere Perl-Module nützlich, um dieses Skript auszuführen:

· „Getopt::Long“ für die Optionsverwaltung.

· „DBI“, „DBD::Pg“ zum Herstellen einer Verbindung zu PostgreSQL, „DBD::mysql“ zum Herstellen einer Verbindung zu MySQL und
„DBD::SQLite“ zum Herstellen einer Verbindung mit SQLite.

· „Term::ReadPassword“ für die Option „--ask-pass“.

· „Pod::Usage“ für die Selbstextraktion von Dokumenten („--man“ „--opt“ „--help“).

· „threads“ für die experimentelle Thread-Version mit der Option „--threads“.

· „Digest::MD5“ für MD5-Prüfsumme mit SQLite.

Module werden vom Skript nur dann geladen, wenn sie tatsächlich benötigt werden.

ALGORITHM


Ziel des Algorithmus ist es, den Inhalt zweier Tabellen, möglicherweise auf unterschiedlichen, zu vergleichen
Remote-Server mit minimalem Netzwerkverkehr. Es wird in drei Phasen durchgeführt.

1.
Für die Zieltabelle wird auf jeder Seite eine Prüfsummentabelle berechnet.

2.
Auf jeder Seite wird eine Übersichtstabelle der ersten Ebene berechnet, indem Teile davon aggregiert werden
Prüfsummentabelle. Anschließend werden weitere Ebenen der zusammenfassenden Aggregation durchgeführt, bis dies der Fall ist
nur eine Zeile in der letzten Tabelle, die dann eine globale Prüfsumme für das Ganze speichert
anfängliche Zieltabellen.

3.
Ausgehend von den oberen Übersichtstabellen werden die aggregierten Prüfsummen beider verglichen
Seiten, um nach Unterschieden zu suchen, bis hin zur anfänglichen Prüfsummentabelle. Verschiedene Schlüssel
Tupel werden angezeigt.

CHECKSUM TABELLE
In der ersten Phase wird die anfängliche Prüfsummentabelle berechnet T(0) auf jeder Seite. Vorausgesetzt, dass Haupt
ist die Tabellenschlüsselspalte und Spalten sind die Tabellendatenspalten, die überprüft werden sollen
Unterschiede, dann wird es durch Abfragen der Zieltabelle durchgeführt T wie folgt:

TABELLE ERSTELLEN T(0) WIE
SELECT-Schlüssel AS pk, -- Primärschlüssel
checksum(key) AS kcs, -- Schlüsselprüfsumme
checksum(key || cols) AS tcs – Tupelprüfsumme
VON t;

Der Anfangsschlüssel bleibt erhalten, da er am Ende zur Darstellung unterschiedlicher Schlüssel verwendet wird. Der
rational für die kcs In der Spalte wird die Verteilung der Schlüsselwerte randomisiert, um ein Gleichgewicht zu erreichen
Aggregate in der nächsten Phase. Der Schlüssel muss auch in der Prüfsumme auftauchen, sonst Inhalt
Der Austausch zwischen zwei Schlüsseln würde in manchen Fällen nicht erkannt werden.

ZUSAMMENFASSUNG TISCHE
Jetzt berechnen wir durch Gruppierung einen Satz kaskadierender Übersichtstabellen f (Faltungsfaktor) Prüfsummen
in jeder Phase zusammen. Die Gruppierung basiert auf einer Maske auf der kcs Spalte zu nehmen
Vorteil der Prüfsummen-Randomisierung. Ab p = 0 wir bauen:

TABELLE T(p+1) ALS ERSTELLEN
SELECT kcs & mask(p+1) AS kcs, -- Teilmenge der Schlüsselprüfsumme
XOR(tcs) AS tcs – Tupel-Prüfsummenzusammenfassung
VON T(p)
GROUP BY kcs & mask(p+1);

Die Maske (p) ist so definiert, dass sie im Durchschnitt gruppiert f Prüfsummen zusammen: Maske"(0)
= Decke2(Größe); mask(p) = mask(p-1)/f; Dies führt zu einer Hierarchie von Tabellen, von denen jede einzelne ist
eine kleinere Zusammenfassung des vorherigen:

Grad des 0
Prüfsummentabelle, Größe Zeilen, also so viele Zeilen wie die Zieltabelle.

Grad des 1
erste Übersichtstabelle, (Größe/f) Zeilen.

Grad des p
Zwischenübersichtstabelle, (Größe/f**p) Zeilen.

Grad des n-1
eine vorletzte Übersichtstabelle, weniger als f Zeilen.

Grad des n
Letzte Übersichtstabelle, Maske ist 0, 1 Zeile.

Es ist wichtig, dass auf beiden Seiten die gleichen Masken verwendet werden, damit es zu Aggregationen kommt
identisch, so dass übereinstimmende Inhalte auf beiden Seiten verglichen werden können.

SUCHE FÜR UNTERSCHIEDE
Nachdem all diese Stütztische auf beiden Seiten aufgebaut sind, beginnt die Suche nach Unterschieden.
Bei der Prüfung der Prüfsummenzusammenfassung der letzten Tabellen (Level n) mit nur einer Zeile ist es
im Grunde ein Vergleich der Prüfsumme des gesamten Tabelleninhalts. Wenn sie übereinstimmen, dann
Beide Tabellen sind gleich und wir sind fertig. Andernfalls, wenn diese Prüfsummen unterschiedlich sind, einige
Es sind Untersuchungen erforderlich, um fehlerhafte Schlüssel zu erkennen.

Die Untersuchung erfolgt, indem man die Tabellenhierarchie durchgeht und nach allen sucht kcs
bei dem es einen Unterschied in der Prüfsumme zur vorherigen Ebene gab. Die gleiche Abfrage ist
auf beiden Seiten in jeder Phase durchgeführt:

SELECT kcs, tcs
VON T(p)
WHERE kcs & mask(p+1) IN (kcs-with-diff-checksums-from-level-p+1)
ORDER BY kcs [und auf Ebene 0: , id];

Und die Ergebnisse beider Seiten werden zusammengeführt. Bei der Durchführung des Zusammenführungsvorgangs vier
Fälle können auftreten:

1.
Beide kcs und tcs passen. Dann gibt es keinen Unterschied.

2.
Obwohl kcs passt, tcs nicht. Dann das kcs soll als nächstes untersucht werden
Ebene, da die Prüfsummenzusammenfassung unterschiedlich ist. Wenn wir bereits auf der letzten Ebene sind, dann
Der fehlerhafte Schlüssel kann angezeigt werden.

3.
Nein kcs Übereinstimmung, eine Ergänzung kcs auf der ersten Seite. Dann das kcs entsprechen
Schlüssel, die zum Synchronisieren der zweiten Tabelle mit der ersten eingefügt werden müssen.

4.
Nein kcs Übereinstimmung, eine Ergänzung kcs auf der zweiten Seite. Dann das kcs entsprechen
Schlüssel, die gelöscht werden müssen, um die zweite Tabelle mit der ersten zu synchronisieren.

Die Fälle 3 und 4 sind einfach symmetrisch und es ist nur eine Interpretation, um zu entscheiden, ob
Es handelt sich um eine Einfügung oder eine Löschung, wobei die erste Seite als Referenz verwendet wird.

ANALYSE
Lassen n sei die Anzahl der Zeilen, r die Zeilengröße, f der Faltfaktor, k die Anzahl der
zu erkennende Unterschiede, c die Prüfsummengröße in Bits, dann die Kosten für die Identifizierung
Unterschiede und die Fehlerquote beträgt:

Netzwerk Volumen
ist besser als k*f*ceil(log(n)/log(f))*(c+log(n)). Die Inhalte von k Blöcke der Größe f
wird auf die Tiefe des Baums übertragen, und jeder Blockidentifikator hat eine Größe log (n) und
enthält eine Prüfsumme c. Es ist unabhängig von r, und du willst k<<n. Das Volumen der
Bei SQL-Anfragen geht es um k*log(n)*ceil(log(n)/log(f)), als Liste der nicht übereinstimmenden
Prüfsummen k*log(n) kann über die Baumtiefe gezogen werden.

Anzahl of Zugriffe (auf jeder Seite, die Algorithmus is symmetrisch)
Minimum ist 6+decke(log(n)/log(f)) für gleiche Tabellen beträgt das Maximum 6+2*Decke(log(n)/log(f)).

Scheibe I / O der Verkehr
ungefähr n*r+n*ln(n)*(f/(f-1)).

falsch Negativ Wahrscheinlichkeit
dh Einige der Tabellen gelten als gleich, obwohl sie unterschiedlich sind. Mit einem
Perfekte Prüfsummenfunktion, dies ist die Wahrscheinlichkeit einer Prüfsummenkollision an jedem Punkt
wo sie berechnet werden und anders hätten sein sollen: ungefähr
k*ceil(log(n)/log(f))*2**-c. Für eine Tabelle mit einer Million Zeilen werden 1000 Änderungen erwartet
Standardalgorithmus-Parameterwerte, hier geht es um 2 ** 10 *3/2**64, das ist ungefähr eins
Chance in 2 ** 52 Zusammenführungsläufe.

Je niedriger der Faltfaktor ist f Je besser für das Netzwerkvolumen, aber desto höher
Besser für die Anzahl der Anfragen und Festplatten-I/Os: die Wahl von f ist ein Kompromiss.

Je niedriger die Prüfsummengröße c, desto besser für das Netzwerkvolumen, aber desto schlechter für die
falsch negative Wahrscheinlichkeit.

Wenn die verfügbare Bandbreite angemessen ist, wird der Vergleich höchstwahrscheinlich CPU-gebunden sein:
Die Zeit wird hauptsächlich für die Berechnung der anfänglichen Prüfsummentabelle aufgewendet. Also, wenn Sie es sind
Wenn Sie planen, häufig nach Unterschieden zu suchen, sollten Sie erwägen, eine Tupel-Prüfsumme mit zu führen
einen Trigger und möglicherweise auch eine Schlüsselprüfsumme und rufen Sie mit „--tuple-checksum“ und auf
entweder „--key-checksum“ oder „--use-key“.

IMPLEMENTIERUNG PROBLEME
Die Prüfsummenimplementierung liefert Ganzzahlen, die eine konstante Länge haben und leicht zu verarbeiten sind
anschließend manipulieren.

Die xor Aggregat ist eine gute Wahl, da es dabei kein Überlaufproblem gibt
berücksichtigt alle Bits der Eingabe und kann leicht für beliebige Binärdaten definiert werden. Der
Summe aggregat ist auch in Ordnung, erfordert aber einen zugrunde liegenden Integer-Typ.

NULL-Werte müssen entsprechend beachtet werden.

Der Faltfaktor und alle Module werden als Zweierpotenz angenommen, um eine Maske zu verwenden.

Es gibt eine spezielle Verwaltung großer Lösch- oder Einfügungsblöcke, die implementiert ist
obwohl in der algorithmischen Übersicht und Komplexitätsanalyse nicht näher erläutert.

Es gibt einige Bemühungen, eine PostgreSQL/MySQL-kompatible Implementierung davon zu erstellen
Algorithmus, der Hacks hinzufügte, um mit Typkonvertierungen und anderen Dingen umzugehen.

Dieses Skript ist einigermaßen getestet, aber aufgrund seines Proof-of-Concept-Charakters gibt es viele
Optionen, deren Kombination nicht alle getestet werden kann.

HINWEIS
Wenn sich die zu vergleichenden Tabellen in derselben Datenbank befinden, kann eine einfache SQL-Abfrage die Tabellen extrahieren
Unterschiede. Angenommene Tabellen T1 und T2 mit Primärschlüssel id und Nicht-Null-Inhalte frustrierten,
dann ihre Unterschiede, das ist wie T2 weicht von der Referenz ab T1, wird durch die zusammengefasst
folgende Abfrage:

SELECT COALESCE(T1.id, T2.id) AS Schlüssel,
FALL, WENN T1.id NULL IST, DANN „LÖSCHEN“
WENN T2.id NULL IST, DANN „INSERT“
ELSE 'UPDATE'
END AS-Vorgang
FROM T1 FULL JOIN T2 USING (id)
WO T1.id NULL IST – LÖSCHEN
ODER T2.id IST NULL – EINFÜGEN
ODER T1.data <> T2.data – UPDATE

REFERENZEN
Auf einer Konferenz wurde ein Artikel über dieses Tool und seinen Algorithmus vorgestellt: Verbund Vergleich
of Datenbank Tische by Fabian Coelho, In der dritten internationalen Konferenz über Fortschritte in
Datenbanken, Wissen und Datenanwendungen (DBKDA), S. 23–28, St. Marteen, Niederlande
Antillen, Januar 2011. ISBN: 978-1-61208-002-4. Copyright IARIA 2011. Online bei Think
Geisthttp://www.thinkmind.org/index.php?view=article&articleid=dbkda_2011_2_10_30021>.

Der Algorithmus und das Skript wurden inspiriert von Zähmung die Verteilt Datenbank Problem: A Wohncontainer
Studie Die richtigen MySQL by Giuseppe Maxia in Sys Administrator Bd. 13, Nr. 8, August 2004, S. 29–40. Sehen
Perl-Mönchehttp://www.perlmonks.org/index.pl?node_id=381053> für Details. In diesem Papier,
Es werden drei Algorithmen vorgestellt. Der erste vergleicht zwei Tabellen mit einer Prüfsumme
Technik. Der zweite findet UPDATE- oder INSERT-Unterschiede basierend auf einer 2-stufigen Prüfsumme
und Zusammenfassung) Tabellenhierarchie. Der Algorithmus ist asymmetrisch, ebenso wie verschiedene Abfragen
an den beiden Tabellen durchgeführt, um sie zu vergleichen. Es scheint, dass das Netzwerkverkehrsaufkommen in Ordnung ist
k*(f+(n/f)+r), dass es ein probabilistisch fehlerhaftes Zusammenführungsverfahren gibt und dass es funktioniert
Annahmen über die Verteilung von Schlüsselwerten. Der dritte Algorithmus sucht nach DELETE
Unterschiede basieren auf der Zählung, mit der impliziten Annahme, dass es nur solche gibt
Unterschiede.

Im Gegensatz zu diesem Ansatz implementiert unser vollständig symmetrischer Algorithmus alle drei Aufgaben
auf einmal, um UPDATE, DELETE und INSERT zwischen den beiden Tabellen zu finden. Die Prüfsumme und
Zusammenfassende Ideen auf hierarchischer Ebene werden wiederverwendet und verallgemeinert, um den Algorithmus zu reduzieren
Komplexität.

Aus Sicht der Implementierung ist das Skript bei vielen so parametrisch wie möglich
Optionen und macht wenige Annahmen über Tabellenstrukturen, -typen und -werte.

Verwenden Sie pg_comparator online über die Dienste von onworks.net



Neueste Linux- und Windows-Online-Programme