it-swarm.com.de

So fügen Sie eine Spalte zu einer großen Tabelle in MySQL hinzu

Ich bin ein PHP Entwickler, also sei nicht streng. Ich habe eine große Tabelle ~ 5,5 GB Speicherauszug. Unsere PM hat beschlossen, eine neue Spalte darin zu erstellen Tabelle ist InnoDB, also was ich versucht habe:

  1. Ändern Sie die Tabelle im Bildschirm mit der Tabellensperre. Hat ~ 30 Stunden gedauert und nichts. Also habe ich einfach aufgehört. Zuerst habe ich einen Fehler gemacht, weil ich nicht alle Transaktionen beendet habe, aber das zweite Mal war kein Multilock. Status war copy to tmp table.

  2. Da ich für diese Tabelle auch eine Partitionierung anwenden muss, entscheiden wir uns, einen Dump zu erstellen, umzubenennen und eine Tabelle mit demselben Namen und neuer Struktur zu erstellen. Aber Dump macht eine strenge Kopie (zumindest habe ich nichts anderes gefunden). Also habe ich hinzugefügt, um eine neue Spalte mit sed zu sichern und abzufragen. Aber einige seltsame Fehler begannen. Ich glaube, es wurde durch Zeichensatz verursacht. Die Tabelle in utf-8 und die Datei wurden nach sed zu us-ascii. Ich habe also Fehler (unbekannter Befehl '\' ') bei 30% der Daten erhalten. Das ist also auch ein schlechter Weg.

Was sind andere Optionen, um dies zu erreichen und die Leistung zu beschleunigen (ich kann es mit PHP-Skript tun, aber es wird ewig dauern). Was ist die Leistung von INSERT SELECT In diesem Fall.

Vielen Dank für jeden Fortschritt.

13
ineersa

Verwenden Sie MySQL Workbench . Sie können mit der rechten Maustaste auf eine Tabelle klicken und "An SQL Editor senden" -> "Anweisung erstellen" auswählen. Auf diese Weise wird nicht vergessen, Tabellen "Eigenschaften" hinzuzufügen (einschließlich CHARSET oder COLLATE).
Bei dieser riesigen Datenmenge würde ich empfehlen, entweder die Tabelle oder die von Ihnen verwendete Datenstruktur zu bereinigen (ein guter DBA ist praktisch). Wenn nicht möglich:

  • benennen Sie die Tabelle um (ALTER) und erstellen Sie eine neue mit dem Skript CREATE, das Sie von Workbench erhalten. Sie können diese Abfrage auch um das neue Feld erweitern, das Sie benötigen
  • BULK LADE die Daten von der alten Tabelle in die neue:
    SET FOREIGN_KEY_CHECKS = 0;
    SET UNIQUE_CHECKS = 0;
    SET AUTOCOMMIT = 0;
    INSERT INTO new_table (fieldA, fieldB, fieldC, ..., fieldN)
       SELECT fieldA, fieldB, fieldC, ..., fieldN
       FROM old_table
    SET UNIQUE_CHECKS = 1;
    SET FOREIGN_KEY_CHECKS = 1;
    COMMIT;
    

    Auf diese Weise vermeiden Sie die Indizierung/etc, um Datensatz für Datensatz auszuführen. Das "Update" der Tabelle wird immer noch langsam sein (da die Datenmenge sehr groß ist), aber dies ist der schnellste Weg, den ich mir vorstellen kann.

    BEARBEITEN: Lesen Sie diesen Artikel, um Details zu den in der obigen Beispielabfrage verwendeten Befehlen zu erhalten;)
12
user23243

alter table add column, algorithm=inplace, lock=none ändert eine MySQL 5.6-Tabelle, ohne die Tabelle zu kopieren und ohne Auswirkungen zu sperren.

Gerade erst gestern getestet, hat die Masse 70.000 Zeilen in eine Partitionstabelle mit 280.000 Zeilen 7 und 10.000 Zeilen in jede Partition eingefügt, wobei dazwischen 5 Sekunden Ruhezeit liegen, um einen anderen Durchsatz zu ermöglichen.

Startete die Masseneinfügungen, dann startete in einer separaten Sitzung die Online-Anweisung alter oben in MySQL Workbench, die alter wurde vor den Einfügungen beendet, zwei neue Spalten wurden hinzugefügt, und aus der Änderungsbedeutung ergaben sich keine Zeilen MySQL hat keine Zeilen kopiert.

5
SAK

Ihre Idee ist eine anständige Methode, aber ohne die Fehler oder den Befehl, den Sie ausgeführt haben, können wir Ihnen nicht helfen.

Eine bekannte Methode zum Vornehmen von Online-Änderungen an großen Tabellen ist jedoch pt-online-schema-change . Der vereinfachte Überblick über die Funktionsweise dieses Tools wird aus der Dokumentation kopiert:

pt-online-schema-change erstellt eine leere Kopie der zu ändernden Tabelle, ändert sie wie gewünscht und kopiert dann Zeilen aus der ursprünglichen Tabelle in die neue Tabelle. Wenn die Kopie fertig ist, wird die ursprüngliche Tabelle entfernt und durch die neue ersetzt. Standardmäßig wird auch die ursprüngliche Tabelle gelöscht.

Diese Methode kann auch eine Weile dauern, aber während des Vorgangs kann die ursprüngliche Tabelle vollständig verwendet werden.

5
Derek Downey

Derzeit ist die beste Option zum Ändern großer Tabellen wahrscheinlich https://github.com/github/gh-ost

gh-ost ist eine auslöserlose Online-Schema-Migrationslösung für MySQL. Es ist testbar und bietet Pausierbarkeit, dynamische Steuerung/Neukonfiguration, Überwachung und viele betriebliche Vorteile.

gh-ost erzeugt während der gesamten Migration eine geringe Arbeitslast auf dem Master, die von der vorhandenen Arbeitslast in der migrierten Tabelle entkoppelt ist.

Es basiert auf jahrelanger Erfahrung mit vorhandenen Lösungen und ändert das Paradigma der Tabellenmigrationen.

1
iJanki

Ich denke Mydumper/Myloader ist ein gutes Werkzeug für Operationen wie diese: Wird von Tag zu Tag besser. Sie können Ihre CPUs nutzen und Daten parallel laden: http://www.percona.com/blog/2014/03/10/new-mydumper-0-6-1-release-offers-several- Performance- und Usability-Features /

Ich habe es geschafft, Hunderte von Gigabyte MySQL-Tabellen in Stunden zu laden.

Das Hinzufügen einer neuen Spalte ist schwierig, da MySQL die gesamte Tabelle mit ALTER TABLE... In den Speicherbereich TMP kopiert. Obwohl MySQL 5.6 angibt, dass Online-Schemaänderungen vorgenommen werden können, habe ich ' Es ist mir nicht gelungen, sie online für massive Tische ohne Sperrkonflikte zu erstellen.

1
Kubilay