Ich habe eine InnoDB-Tabelle mit 700 GB, in die ich keine Daten mehr schreibe (nur lesen). Ich möchte die älteren darin enthaltenen Daten löschen und den Speicherplatz zurückfordern (da mir der Speicherplatz ausgeht). Der Lösch-Teil ist ziemlich einfach, da ich einen Auto-Inc-Primärindex habe, mit dem ich einfach in Stücken iterieren und die Zeilen löschen kann, aber das bringt mir nicht den Platz zurück. Ich OPTIMIZE TABLE
gehe davon aus , dass dies bei einem 700-GB-Tisch jedoch für immer dauern könnte. Gibt es also eine andere Option, die ich übersehen habe?
Edit von RolandoMySQLDBA
Angenommen, Ihre Tabelle ist mydb.mytable
, führen Sie die folgende Abfrage aus und veröffentlichen Sie sie hier, damit Sie den für die Schrumpfung der Tabelle erforderlichen Speicherplatz bestimmen können:
SELECT
FORMAT(dat/POWER(1024,3),2) datsize,
FORMAT(ndx/POWER(1024,3),2) ndxsize,
FORMAT((dat+ndx)/POWER(1024,3),2) tblsize
FROM (SELECT data_length dat,index_length ndx
FROM information_schema.tables WHERE
table_schema='mydb' AND table_name='mytable') A;
Wir müssen auch die Tabellenstruktur sehen, wenn dies erlaubt ist.
Edit von Noam
Dies ist die Ausgabe der Abfrage:
datsize ndxsize tblsize
682.51 47.57 730.08
Dies ist die Tabellenstruktur ( SHOW CREATE TABLE
)
`CREATE TABLE `mybigtable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`tid` bigint(20) NOT NULL,
`text` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`ft` tinyint(1) NOT NULL,
`irtsd` bigint(20) NOT NULL,
`irtuid` int(11) NOT NULL,
`rc` int(11) NOT NULL,
`r` tinyint(1) NOT NULL,
`e` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `timezone` varchar(5) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uid_tid` (`uid`,`tid`)) ENGINE=InnoDB AUTO_INCREMENT=2006963844 DEFAULT CHARSET=utf8`
ALTER TABLE ... ENGINE=InnoDB;
(sofern Sie den Raum dazu haben). Die meisten sind nur mit ihren sehr schnellen SSDs zufrieden und würden sich keine Sorgen mehr machen.Antworten:
Das ist eine gute Frage. Sie haben mehrere Lösungen, aber Ihr Tisch ist ziemlich groß, so dass keiner schmerzfrei sein wird :)
Sie haben drei Möglichkeiten, um InnoDB-Tabellen zu "verkleinern":
1. TABELLE OPTIMIEREN
Sie können verwenden,
OPTIMIZE TABLE
wie Sie es erwähnt haben, aber Sie sollten sich um dieinnodb_file_per_table
Variable kümmern :Lassen Sie mich erklären:
Mit
OPTIMIZE TABLE
InnoDB-Tabellen wird die Tabelle gesperrt, die Daten werden in eine neue saubere Tabelle kopiert (daher wird das Ergebnis verkleinert), die ursprüngliche Tabelle gelöscht und die neue Tabelle mit dem ursprünglichen Namen umbenannt. Aus diesem Grund sollten Sie darauf achten, dass das Doppelte des Volumens Ihrer Tabelle auf Ihrer Festplatte verfügbar ist (während des Betriebs benötigen Sie 2x700 GB).Wenn Sie sich in der innodb_file_per_table = ON befinden. Alle Tabellen haben die richtige Datendatei. Die
OPTIMIZE
Anweisung erstellt also eine neue Datendatei (~ 700 GB), wenn der Vorgang abgeschlossen ist. MySQL löscht die ursprüngliche Datei und benennt die neue um (so dass die 700 GB - wahrscheinlich weniger, weil sie verkleinert werden - der Daten am Ende Während des Vorgangs erzeugte Daten werden freigegeben.)Wenn Sie sich in der Tabelle innodb_file_per_table = OFF befinden. Alle Daten werden in eine Datendatei geschrieben : ibdata . Diese Datei hat eine traurige Besonderheit, sie kann nicht verkleinert werden. Während des
OPTIMIZE
Vorgangs wird Ihre neue Tabelle erstellt (in der Nähe von 700 GB), aber auch nach dem Löschen und Umbenennen (und dem Ende derOPTIMIZE
Phase) werden Ihre ibdata-Daten nicht die ~ 700 GB freigeben. Sie wollten also einige Daten freigeben, haben aber 700 GB mehr cool, nicht wahr?2. ALTER TABLE
Sie können auch eine
ALTER TABLE
Anweisung verwenden, die wieALTER TABLE
folgt funktioniertOPTIMIZE TABLE
. Sie können einfach verwenden:3. ALTER TISCH (ONLINE)
Das Problem ist
OPTIMIZE
undALTER TABLE
dass es den Tisch während des Betriebs sperrt. Sie können das Percona-Tool verwenden: pt-online-schema-change (aus Percona Toolkit: link ). pt-online-schema ... erstellt einen Mechanismus mit Triggern und temporären Tabellen, mit denen Sie zulassen, dass die Originaltabelle während des Vorgangs zum Lesen und Schreiben zur Verfügung steht. Ich benutze dieses Tool in der Produktion für den großen,ALTER
es ist ziemlich cool.Beachten Sie, dass Sie
FOREIGN KEY
auf Ihre Tabelle, FK, verwiesen haben sollten und das Risiko eines Chaos auslösen. Fragen Sie Folgendes ab, um diese Voraussetzungen zu überprüfen:So benutze ich pt-online-schema-change:
Beachten Sie, dass mein Hinweis zu innodb_file_per_table auch für diese Lösung zutrifft.
4. mysqldump
Die letzte Lösung besteht darin, alle Datenbanken aus einem Speicherauszug neu zu erstellen. Schrecklich lang, aber schrecklich effizient. Beachten Sie, dass dies die einzige Lösung ist, um die ibdata-Datei zu verkleinern.
Max.
quelle
Wenn Sie wenig Speicherplatz haben, würde ich vorschlagen, dass Sie genau wie Max mit pt-online-schema-change (ONLINE) vorschlagen. Ich war mit einem viel kleineren Tisch (200 GB) in der gleichen Situation und entschied mich, gleichzeitig eine Komprimierung durchzuführen. Etwas in dieser Richtung sollte funktionieren:
Dies funktioniert nur, wenn Sie sich im Barracuda-Dateiformat und im COMPACT-Format der Tabelle befinden. Außerdem muss innodb_file_per_table aktiviert sein. Dies kann Wunder an der Größe Ihrer Tabelle bewirken, insbesondere wenn viel Text vorhanden ist und Sie eine kleinere KEY_BLOCK_SIZE wie 8 KB oder sogar 4 KB verwenden (die Standardeinstellung ist 16 KB). Sie können auch überprüfen, wie viel Speicherplatz Sie mit mehreren Benchmarks für dieses Problem in anderen Blogs gewinnen können. In der MySQL-Dokumentation werden jedoch 25% bis 50% (für mich waren es fast 90%) angegeben.
Beachten Sie, dass dies auch die Leistung beim Ausführen von SELECTs beeinträchtigen kann (aus der MySQL-Dokumentation):
MySQL muss die Daten auch dekomprimieren, wenn sie nicht im Pufferpool sind. Seid also gewarnt.
Das hat in meinem Fall wirklich gut funktioniert. Ich hatte einen langen Text. Aus 200 GB wurden 26 GB. Aufführungen wurden nicht verändert.
Weitere Informationen finden Sie unter folgenden Links:
https://dev.mysql.com/doc/refman/5.5/de/innodb-compression-usage.html
https://dev.mysql.com/doc/refman/5.5/de/innodb-compression-internals.html
quelle