Ich habe eine MySQL -Datenbank mit einer Größe von bis zu 17 GB und 38 Millionen Einträgen. Im Moment muss ich sowohl die Größe einer Spalte vergrößern (varchar 40 auf varchar 80) als auch weitere Spalten hinzufügen.
Viele der Felder sind indiziert, einschließlich der, die ich ändern muss. Es ist Teil eines einzigartigen Paares, das für die Anwendungen benötigt wird. Bei dem Versuch, die Änderung gestern vorzunehmen, lief die Abfrage fast vier Stunden lang ohne Abschluss, als ich beschloss, unseren Ausfall zu reduzieren und den Dienst einfach wieder hoch zu bringen.
Was ist der effizienteste Weg, um Änderungen an etwas dieser Größe vorzunehmen?
Viele dieser Einträge sind ebenfalls alt, und wenn es eine gute Möglichkeit gibt, die Shard-Einträge zu sortieren, stehen sie dennoch zur Verfügung, die bei diesem Problem helfen könnten, indem sie die Tabelle viel überschaubarer machen.
Mit MySQL 5.1 und erneut mit 5.5 wurden bestimmte alter-Anweisungen erweitert, um nur die Struktur zu ändern, ohne die gesamte Tabelle neu schreiben zu müssen ( Ссылка - Suche nach In-Place. Die Verfügbarkeit von diesem hängt jedoch von der Art der Änderung, die Sie machen, und der verwendeten Engine ab, der meiste Wert kommt von InnoDB Plugin. Im Falle Ihrer spezifischen Änderungen würde jedoch die gesamte Tabelle neu geschrieben werden.
Wenn wir auf diese Probleme stoßen, versuchen wir normalerweise, Replika-Datenbanken zu nutzen. Solange Sie hinzufügen und nicht entfernen, können Sie Ihre DDL zuerst für das Replikat ausführen und dann einen kurzen Ausfall planen, um das Replikat an die Master-Rolle zu übertragen. Wenn Sie auf RDS sind, ist dies sogar einer ihrer empfohlenen Verwendungszwecke für ihre Replikat-Instanzen. Ссылка .
Einige andere Alternativen umfassen:
INTO OUTFILE
, um eine Tabellensperre zu vermeiden). Nach Abschluss können Sie ein Wartungsfenster und REPLACE INTO
oder UPDATE
alle Datensätze einplanen, die sich seit der ursprünglichen Datenkopie in der Originaltabelle geändert haben. Sobald die Aktualisierung abgeschlossen ist, werden die Änderungen in RENAME TABLE...
der beiden Tabellen aufgehoben. Sie haben einige Möglichkeiten.
In jedem Fall sollten Sie eine Sicherungskopie erstellen, bevor Sie das tun.
Eine Möglichkeit besteht darin, Ihren Dienst offline zu schalten und an Ort und Stelle zu betreiben, wie Sie es bereits versucht haben. Wenn Sie das tun, sollten Sie Schlüsselüberprüfungen und Einschränkungen deaktivieren.
%Vor%Dadurch wird der ALTER TABLE-Vorgang beschleunigt. Es wird die Indizes auf einmal neu generieren, wenn Sie KEYS aktivieren.
Eine weitere Möglichkeit besteht darin, eine neue Tabelle mit dem gewünschten neuen Schema zu erstellen, dann die Schlüssel in der neuen Tabelle zu deaktivieren, dann wie von @Bader vorgeschlagen vorzugehen und den Inhalt der alten Tabelle einzufügen.
Nachdem Ihre neue Tabelle erstellt wurde, werden Sie die darin enthaltenen Schlüssel erneut aktivieren, dann die alte Tabelle in einen Namen wie "old_bigtable" umbenennen und dann die neue Tabelle in "bigtable" umbenennen.
Es ist möglich, dass Sie Ihren Service online halten können, während Sie die neue Tabelle ausfüllen. Aber das könnte schlecht funktionieren.
Eine dritte Möglichkeit besteht darin, Ihren riesigen Tisch (in eine flache Datei) zu entladen und ihn dann in eine neue Tabelle mit dem neuen Layout zu laden. Das ist so ähnlich wie bei der zweiten Möglichkeit, außer dass Sie eine kostenlose Tabellensicherung erhalten. Sie können dies mit SELECT DATA INTO OUTFILE
und LOAD DATA INFILE
ziemlich schnell machen. Dazu müssen Sie Zugriff auf das Dateisystem Ihres Server-Rechners haben.
Deaktivieren Sie in allen Fällen die Einschränkungen und Schlüssel, um die Dinge schneller zu machen.
Erstellen Sie eine neue Tabelle mit der neuen gewünschten Struktur mit einem anderen Namen, zB NewTable.
Fügen Sie dann mithilfe der folgenden Abfrage Daten aus der alten Tabelle in diese neue Tabelle ein:
%Vor%Danach können Sie die alte Tabelle löschen und die neue Tabelle in den ursprünglichen Namen umbenennen
%Vor%Ich habe diesen Ansatz auf einer sehr großen Tabelle versucht und es ist viel viel schneller als die Tabelle zu ändern.