1. Einführung
Projektadresse: https://github.com/seanlook/p...
pt-table wird häufig zur Datenkonsistenzüberprüfung in einem Master-Slave verwendet Umgebung. -Checksum-Tool, sein Prinzip und der Implementierungsprozess wurden zuvor in einem Artikel beschrieben: Verwenden Sie pt-table-checksum, um die MySQL-Datenkonsistenz in der Produktionsumgebung zu überprüfen. Bei der DBA-Arbeit werden jedoch einige Überprüfungen der Konsistenz der beiden Tabellen durchgeführt, und es besteht keine Master-Slave-Beziehung zwischen den beiden Tabellen. Das PT-Tool spielt die in der Master-Datenbank durchgeführten Prüfaktionen basierend auf dem Binlog-In ab Die Slave-Datenbank ist nicht mehr anwendbar.
Es wird immer solche besonderen Anforderungen geben, wie zum Beispiel die Migration von einer Alibaba Cloud RDS-Instanz zu einer selbst erstellten MySQL-Instanz. Die Implementierungsmethode für den Datenübertragungsdienst ist die tabellenbasierte Batch-Datenextraktion plus Binlog-Abonnement Der obligatorische Zeilenmodus führt dazu, dass pt-table-checksum nicht die Berechtigung hat, die Sitzung vorübergehend in eine Anweisung zu ändern. Eine weitere Anforderung besteht darin, den Zeichensatz der gesamten Bibliothek zu konvertieren: Die Bibliothekstabellendefinitionen sind alle utf8, aber die Anwendungsverbindung verwendet den Standard-Latin1. Um den Verbindungszeichensatz und den Tabellenzeichensatz zu vereinheitlichen, können die Daten nur mit Latin1 exportiert werden , und dann mit UTF8-Import, in diesem Fall Datenkonsistenzprüfung, ganz zu schweigen davon, dass das Binlog-Analyseprogramm keine Anweisung (z. B. Kanal) unterstützt, der Inhalt der alten und neuen Bibliothek unterschiedlich ist und der von pt berechnete Prüfwert -table-checksum wird unterschiedlich und ungültig sein.
Deshalb kam ich auf die Idee, mich auf pt-table-checksum zu beziehen und habe selbst eines geschrieben: px-table-checksum.
2. Implementierungsmethode
Die Gesamtidee besteht darin, aus der pt-table-checksum zu lernen, ein Datenelement, beispielsweise 1000 Zeilen, stapelweise aus der Quelldatenbank zu entnehmen. Berechnen Sie den CRC32-Wert und verwenden Sie dieselbe Anweisung im Ziel. Die Bibliothek wird einmal ausgeführt und die Ergebnisse werden in einer anderen Bibliothek gespeichert. Anschließend wird überprüft, ob die Chunk-CRC-Werte der entsprechenden Zahlen konsistent sind. Die Kenntnis der Inkonsistenzen reicht nicht aus, um die Unterschiede schnell und bequem zu beheben. Gehen Sie also weiterhin zur Zielbibliothek und zur Quellbibliothek, um die inkonsistenten Zeilen anhand dieser fehlenden oder redundanten Teile zu finden oder geändert und dann die Reparatur-SQL entsprechend generiert. Gibt an, ob die Reparatur automatisch durchgeführt werden soll.
Dann stellt sich die Frage:
Wie bestimmt man die Charge, also wie kommt man an den nächsten Brocken? Ich wollte nicht das tun, was pt-table-checksum macht, nämlich die Blockgröße dynamisch an die Last anzupassen oder sogar die Prüfung auszusetzen, wenn die Anzahl der aktiven Threads den Schwellenwert überschreitet. Die Arbeitsbelastung wäre zu hoch. Derzeit ist die Anzahl der jedes Mal berechneten Chunk-Zeilen festgelegt und kann auf 1000 oder 2000 usw. konfiguriert werden.
Wir müssen also eine Paging-Abfrage gemäß dem Primärschlüssel (automatische Inkrementierung oder Union) und dem eindeutigen Index verwenden. Nach jedem Grenzwert von 1000 wird der letzte in aufsteigender Reihenfolge als Anfang des nächsten verwendet Charge. Daher ist es notwendig, die Schlüsselsituation in der Tabelle zu analysieren und die Abfragebedingungen zu kombinieren. Derzeit können nur Tabellen mit Primärschlüsseln oder eindeutigen Schlüsseln überprüft werden.
Wie kann sichergestellt werden, dass die Quellbibliothek und die Zielbibliothek dasselbe SQL ausführen? In der vorherigen Version verwendeten die Zielbibliothek und die Quellbibliothek mehrere Threads, um Blöcke separat zu berechnen und in der Bibliothek zu speichern. Später wurde mir ein schwerwiegender Fehler bewusst: Wenn beispielsweise auch 1000 Zeilen abgerufen wurden, wenn die Zielbibliothek weniger hatte Daten, der Ausgangspunkt des nächsten Blocks wäre anders, die Vergleichsergebnisse sind einfach ein Chaos.
Daher muss sichergestellt werden, dass die Blöcke mit der gleichen Nummer und dem Startpunkt gleich sein müssen. Deshalb habe ich darüber nachgedacht, eine Warteschlange zu verwenden, um alle in der Quellbibliothek ausgeführten Verifizierungs-SQLs zu speichern , und simulieren Sie das pt-Tool, um es in der Zielbibliothek wiederzugeben. Da mehrere Threads mehrere Tabellen gleichzeitig vergleichen müssen, verbraucht die Warteschlange möglicherweise zu viel Speicher, sodass eine Redis-Warteschlange verwendet wird.
crc32 direkt in der Datenbank berechnen oder die Daten herausnehmen und im Speicher berechnen? Ich habe den Quellcode von pt-table-checksum überprüft und festgestellt, dass er in der Datenbank berechnet wird. Wenn jedoch, wie im ersten Abschnitt erwähnt, die Zielbibliothek und die Quellbibliothek unterschiedliche Zeichensätze verwenden müssen, um die korrekten Daten zu lesen, können sie nur abgefragt und dann verglichen werden. Daher unterstützt px-table-checksum beides und muss nur ein Konfigurationselement angeben.
Überprüfen Sie mehrere Tabellen gleichzeitig. Wenn die Zieldatenbank zur Ausführung herausgenommen wird, sind die Daten in der Quelldatenbank überfüllt wurde erneut geändert und mit der Zieldatenbank synchronisiert, was zu inkonsistenten Berechnungsergebnissen führt, die jedoch nicht behoben werden können. Dies ist der größte Fehler von px-table-checksum im Vergleich zu pt-table-checksum.
Um solche Probleme jedoch so weit wie möglich zu reduzieren (z. B. kann es auch zu Master-Slave-Verzögerungen kommen), wurden mehrere Redis-Warteschlangen speziell entwickelt, und die Zielbibliothek verfügt beispielsweise über mehrere Prüfthreads Für die gleichzeitige Überprüfung wird angegeben, dass der Quellbibliotheksprüfung 8 Threads entsprechen, aber entsprechend der Schreibsituation der Tabelle können 4 Redis-Warteschlangen (derzeit zufällig in die Warteschlange gestellt) und 10 Zielbibliotheksprüfungsthreads konfiguriert werden, um Ungenauigkeitsfaktoren zu reduzieren . Aber aus meiner Sicht werden inkonsistente Daten erfasst. Wenn es nicht viele sind, werden sie manuell überprüft. Wenn die gleichen Daten zweimal inkonsistent sind, dann stimmt etwas nicht. .
3. Einschränkungen
Wenn sich die Daten der Quelltabelle während der Prüfung häufig ändern, können die Prüfergebnisse ungenau sein, was das Problem in Punkt 4 oben darstellt. Offensichtlich ist jede von diesem Programm überprüfte Transaktion separat, im Gegensatz zum PT-Tool, das die Transaktionsreihenfolge jeder SQL-Prüfung strikt garantieren kann. Wenn die Daten jedoch inkonsistent sind, überprüfen Sie sie erneut, dann ist alles in Ordnung. Tatsächlich war es während meiner Online-Nutzung zu 99,9 % korrekt.
Es muss ein Primärschlüssel oder ein eindeutiger Index in der Tabelle vorhanden sein. Wenn nicht, wird das Programm dies überprüfen und beenden.
Varbinay, Blob und andere binäre Felder unterstützen die Reparatur nicht.
Tatsächlich ist dies nicht völlig ununterstützt, es hängt davon ab, wie es verwendet wird. Wenn während der Entwicklung Zeichen zunächst in Bytes umgewandelt und dann in MySQL gespeichert werden, unterstützt dies keine Reparatur. Es gibt eine Möglichkeit, damit umzugehen: Verwenden Sie beim Überprüfen aus der Quellbibliothek die Funktion hex(), reparieren Sie unhex() im SQL und schreiben Sie es zurück.
4. Gebrauchsanweisung
Dieses Python-Programm wurde auf Basis von 2.7 entwickelt und wurde nicht auf 2.6 und 3.x getestet. Sie müssen MySQLdb und Hotqueue vor der Verwendung installieren:
$ sudo pip install MySQL-python hotqueue
Die zu vergleichenden Tabellen und Optionen sollten vollständig konfiguriert sein, also nicht durch Geben Sie die Befehlszeile an (verzeihen Sie, dass die Verwendung von Befehlszeilenparametern die Codemenge erhöht).
4.1 px-table-checksum.py
Hauptprogramm, führen Sie Python px-table-checksum.py aus, um eine Konsistenzprüfung durchzuführen, aber stellen Sie sicher, dass Sie die folgenden Konfigurationsdateioptionen verstehen.
4.2 Settings_checksum.py
Konfigurationsoptionen
CHUNK_SIZE: Anzahl der jedes Mal extrahierten Chunk-Zeilen
REDIS_INFO: Geben Sie die Verwendung der Redis-Warteschlangenadresse an
REDIS_QUEUE_CNT: Die Anzahl der Redis-Warteschlangen. Der Verbraucher (Zielbibliothek) verfügt über einen Eins-zu-Eins-Thread, der die Warteschlange schützt.
REDIS_POOL_CNT: Der Redis-Client-Verbindungspool des Produzenten (Quellbibliothek). Dieses Design soll die durch GIL verursachten Probleme lindern und das Ende der Warteschlange vom Ende der Warteschlange trennen, da bei vielen Tabellen in kurzer Zeit eine große Menge SQL in die Warteschlange gestellt werden kann, um Hotqueue-Konflikte zu vermeiden
CALC_CRC32_DB : True bedeutet, dass der Prüfsummenwert in der Datenbank berechnet wird, und False bedeutet, dass die Blockdaten herausgenommen und in Python berechnet werden. Der Standardwert basiert auf dem Verbindungszeichensatz.
DO_COMPARE: Betriebsmodus
0: Daten nur zur Berechnung extrahieren, nicht auf Konsistenz vergleichen. Sie können später nur
1 im Modus 2: Berechnen und vergleichen vergleichen. Üblicherweise wird vor jeder Berechnung das letzte Ergebnis der zu prüfenden Tabelle gelöscht. Das Vergleichsergebnis gibt lediglich Auskunft darüber, welche Chunk-Nummern inkonsistent sind.
2: Keine Berechnung, nur Vergleich aus t_checkum-Ergebnissen. Im Allgemeinen verbraucht die Berechnung Datenbankressourcen, und Sie können nur die Inkonsistenzen in den Ergebnissen der vorhandenen Prüfsummenberechnung vergleichen. Ähnlich der Option --replicate-check-only des pt-Tools.
GEN_DATAFIX:
Wird in Verbindung mit DO_COMPARE verwendet. Wenn True, bedeutet dies, dass bestimmte inkonsistente Zeilen für inkonsistente Blöcke gefunden und Reparatur-SQL generiert werden. Wenn es False ist, wird nichts unternommen.
RUN_DATAFIX:
Wird in Kombination mit GEN_DATAFIX verwendet. Wenn True, bedeutet dies, dass die generierte Reparatur-SQL in der Zielbibliothek ausgeführt wird. Wenn Sie eine Reparatur einrichten, denken Sie daran, sie nach Abschluss wieder auf „False“ zu ändern, da es sonst beim nächsten Überprüfen einer anderen Tabelle zu einem Unfall kommt. Deshalb habe ich speziell eine Bestätigungsaufforderung für diese Option hinzugefügt.
DB_CHECKSUM: Ein Wörterbuch, das angibt, wo die Prüfsummenergebnisse gespeichert werden
Die Konfigurationsdatei enthält Beispiele, db_name muss angegeben werden und die Tabelle wird automatisch erstellt.
4.3 Settings_cs_tables.py
Die obige Konfigurationsdatei kann zur Steuerung des Programms verwendet werden. Diese Konfigurationsdatei gibt die zu überprüfenden Quell- und Zielbibliotheksinformationen sowie die zu überprüfenden Tabellen an überprüft werden.
TABLES_CHECK: Wörterbuch, das angibt, welche Tabellen auf Konsistenz überprüft werden sollen. Der Datenbankname ist der Schlüssel und die Liste mehrerer Tabellennamen ist der Wert. Die Überprüfung der gesamten Datenbank wird derzeit nicht unterstützt und es wird nicht empfohlen, die Anzahl der gleichzeitig verglichenen Tabellen 8 zu überschreiten
DB_SOURCE: Wörterbuch, das die Verbindungsinformationen der Quelldatenbank angibt
DB_SOURCE: Wörterbuch, das die Verbindung der Zieldatenbankinformationen angibt