Die Geschichte der physischen Löschung von 300 Millionen Datensätzen in MySQL

Einführung

Hallo. Ich bin ningenMe, Webentwickler.

Wie der Titel schon sagt, handelt es sich bei meiner Geschichte um die physische Löschung von 300 Millionen Datensätzen in MySQL.

Das interessierte mich und beschloss, eine Erinnerung (Anleitung) zu erstellen.

Startseite - Alarm

Der Batch-Server, den ich verwende und betreue, verfügt über einen regulären Prozess, der einmal täglich die Daten des letzten Monats von MySQL sammelt.

Normalerweise ist dieser Vorgang innerhalb von etwa einer Stunde abgeschlossen, aber dieses Mal dauerte es sieben oder acht Stunden, bis er abgeschlossen war, und die Warnung hörte nicht auf, aufzutauchen ...

Den Grund finden

Ich habe versucht, den Prozess neu zu starten und mir die Protokolle anzusehen, konnte aber nichts Falsches feststellen.
Die Abfrage wurde korrekt indiziert. Aber als ich darüber nachdachte, was falsch lief, wurde mir klar, dass die Datenbank ziemlich groß ist.

hoge_table | 350'000'000 |

350 Millionen Datensätze. Die Indizierung schien korrekt zu funktionieren, nur sehr langsam.

Die erforderliche Datenerfassung pro Monat betrug etwa 12 Datensätze. Es sieht so aus, als hätte der Auswahlbefehl lange gedauert und die Transaktion wurde lange Zeit nicht ausgeführt.

DB

Es handelt sich im Wesentlichen um eine Tabelle, die jeden Tag um etwa 400 Einträge wächst. Die Datenbank sollte nur Daten für den letzten Monat sammeln, daher wurde erwartet, dass sie genau dieser Datenmenge standhalten würde, aber leider war der Rotationsvorgang nicht enthalten.

Diese Datenbank wurde nicht von mir entwickelt. Ich habe es von einem anderen Entwickler übernommen, daher fühlte es sich immer noch wie eine technische Schuld an.

Irgendwann kam der Punkt, an dem das täglich eingegebene Datenvolumen groß wurde und schließlich seine Grenzen erreichte. Es wird davon ausgegangen, dass bei der Arbeit mit einer so großen Datenmenge eine Trennung dieser Daten erforderlich wäre, was jedoch leider nicht geschehen ist.

Und dann wurde ich aktiv.

Korrektur

Es war sinnvoller, die Größe der Datenbank selbst zu reduzieren und die Verarbeitungszeit zu verkürzen, als die Logik selbst zu ändern.

Die Situation dürfte sich deutlich ändern, wenn man 300 Millionen Datensätze löscht, also habe ich beschlossen, das zu tun ... Ich dachte, das würde auf jeden Fall funktionieren.

Aktion 1

Nachdem ich ein zuverlässiges Backup erstellt hatte, begann ich endlich, Anfragen zu senden.

「Eine Anfrage senden」

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

"..."

"..."

„Hmm... Keine Antwort. Vielleicht dauert der Vorgang lange?“ – dachte ich, aber für alle Fälle schaute ich mir Grafana an und sah, dass die Festplattenlast sehr schnell zunahm.
„Gefährlich“, dachte ich erneut und brach die Anfrage sofort ab.

Aktion 2

Nachdem ich alles analysiert hatte, wurde mir klar, dass die Datenmenge zu groß war, um alles auf einmal zu löschen.

Ich beschloss, ein Skript zu schreiben, das etwa 1 Datensätze löschen konnte, und startete es.

„Ich setze das Skript um“

„Das wird bestimmt klappen“, dachte ich.

Aktion 3

Die zweite Methode funktionierte, erwies sich jedoch als sehr arbeitsintensiv.
Um alles sorgfältig und ohne unnötige Nerven zu erledigen, würde es etwa zwei Wochen dauern. Dennoch entsprach dieses Szenario nicht den Serviceanforderungen, sodass wir davon Abstand nehmen mussten.

Deshalb habe ich mich für Folgendes entschieden:

Kopieren Sie die Tabelle und benennen Sie sie um

Im vorherigen Schritt wurde mir klar, dass das Löschen einer so großen Datenmenge eine ebenso große Last verursacht. Also beschloss ich, mit „Einfügen“ eine neue Tabelle von Grund auf zu erstellen und die Daten, die ich löschen wollte, dorthin zu verschieben.

| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|

Wenn Sie die neue Tabelle auf die gleiche Größe wie oben einstellen, sollte auch die Datenverarbeitungsgeschwindigkeit um 1/7 schneller werden.

Nachdem ich die Tabelle erstellt und umbenannt hatte, begann ich, sie als Mastertabelle zu verwenden. Wenn ich nun die Tabelle mit 300 Millionen Datensätzen lösche, sollte alles in Ordnung sein.
Ich habe herausgefunden, dass das Abschneiden oder Löschen weniger Aufwand verursacht als das Löschen, und habe mich für diese Methode entschieden.

Durchführen

「Eine Anfrage senden」

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

"..."
"..."
„Sie…?“

Aktion 4

Ich dachte, die vorherige Idee würde funktionieren, aber nach dem Senden der Einfügungsanforderung traten mehrere Fehler auf. MySQL verzeiht nichts.

Ich war schon so müde, dass ich dachte, dass ich das nicht mehr machen wollte.

Ich saß da ​​und dachte nach und erkannte, dass es vielleicht zu viele Einfügungsabfragen auf einmal gab ...
Ich habe versucht, eine Einfügungsanforderung für die Datenmenge zu senden, die die Datenbank an einem Tag verarbeiten soll. Passiert!

Nun, danach senden wir weiterhin Anfragen für die gleiche Datenmenge. Da wir die Daten eines Monats entfernen müssen, wiederholen wir diesen Vorgang etwa 35 Mal.

Eine Tabelle umbenennen

Hier war das Glück auf meiner Seite: Alles verlief reibungslos.

Der Alarm ist verschwunden

Die Geschwindigkeit der Stapelverarbeitung wurde erhöht.

Früher dauerte dieser Vorgang etwa eine Stunde, jetzt dauert er etwa 2 Minuten.

Nachdem ich sicher war, dass alle Probleme gelöst waren, habe ich 300 Millionen Datensätze gelöscht. Ich löschte die Tabelle und fühlte mich wie neu geboren.

Zusammenfassung

Mir wurde klar, dass bei der Stapelverarbeitung die Rotationsverarbeitung fehlte, und das war das Hauptproblem. Ein solcher Architekturfehler führt zu Zeitverschwendung.

Denken Sie an die Belastung bei der Datenreplikation beim Löschen von Datensätzen aus der Datenbank? Überlasten wir MySQL nicht.

Wer sich mit Datenbanken auskennt, wird auf ein solches Problem sicher nicht stoßen. Für alle anderen hoffe ich, dass dieser Artikel hilfreich war.

Danke fürs Lesen!

Wir freuen uns sehr, wenn Sie uns mitteilen, ob Ihnen dieser Artikel gefallen hat, ob die Übersetzung klar ist, ob er für Sie nützlich war?

Source: habr.com

Kommentar hinzufügen