Wie nutzen MyISAM und InnoDB HD-Speicherplatz?

7

Meinem MySQL-Server geht schnell der HD-Speicherplatz aus. Die meisten meiner größeren Tabellen verwenden die InnoDB-Engine (ohne geschäftskritischen Grund). In dem Bemühen , den gefürchteten zu vermeiden drop database innodb Speicherplatz zu erholen Antwort, würde ich mag besser zu verstehen , wie die beiden Motoren Speicherung von Daten auf dem Datenträger.

  1. Wenn ich MyISAM verwenden würde, könnte ich den Speicherplatz durch Entfernen von Zeilen einfacher wiederherstellen? Gibt es einen Befehl, den ich zusätzlich zur Abfrage zum Löschen / Abschneiden / Leeren ausführen müsste?
  2. Angenommen, Nummer 1 ist wahr: Wäre es möglich / machbar, vorhandene InnoDB-Tabellen in MyISAM zu konvertieren und auf diese Weise Speicherplatz wiederherzustellen?
Mike B.
quelle

Antworten:

12

Die Verwendung von DiskSpace durch MySQL ist ziemlich vorhersehbar.

Das information_schema kann schnell verraten, wie viel Speicherplatz von beiden Speicher-Engines belegt wird. Es ist jedoch weitaus besser, InnoDB mit innodb_file_per_table zu konfigurieren . Auf diese Weise können Sie den Speicherplatz einzelner InnoDB-Tabellen mikromanagen. Wenn Sie nicht über innodb_file_per_table verfügen, wächst ibdata1 und NIEMALS SCHRINKEN.

Ich habe ein für alle Mal schöne Artikel über Cleaning Up InnoDB geschrieben.

Für MyISAM müssen Sie regelmäßig eine der folgenden Aktionen ausführen:

  • OPTIMIZE TABLE myisam-tablename;;
  • ALTER TABLE myisam-tablename ENGINE=MyISAM; ANALYZE TABLE myisam-tablename;;

Diese komprimieren MyISAM so, dass die MyISAM-Tabellenkomponenten (.MYD und .MYI) keine nicht verwendeten Daten und Indexseiten enthalten.

Mit dieser Abfrage können Sie die Speicherplatznutzung manuell überwachen:

SELECT IFNULL(B.engine,'Total') "Storage Engine", CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Table Size" FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,SUM(data_length+index_length) TSize FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema') AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,(SELECT 3 pw) A ORDER BY TSize;

Dies zeigt an, wie viel Speicherplatz Daten und Index für die Engine Storage Engine belegen. Beachten Sie am Ende der Abfrage die Klausel: (SELECT 3 pw). Ändern Sie die Nummer, um den Bericht in verschiedenen Einheiten zu erstellen

(SELECT 0 pw) for Bytes
(SELECT 1 pw) for KiloBytes
(SELECT 2 pw) for MegaBytes
(SELECT 3 pw) for GigaBytes
(SELECT 4 pw) for TeraBytes
(SELECT 5 pw) for PetaBytes (Write me if you every get numbers this high)

UPDATE 2012-05-26 22:29 EDT

Wenn Sie in InnoDB innodb_file_per_table verwenden, stellen Sie möglicherweise fest, dass zwischen der Dateigröße der .ibdDatei und der Summe von data_length + index_length ein Unterschied besteht.

Für eine InnoDB-Tabelle mydb.mytablesollten Sie Folgendes vergleichen:

  • Ermitteln Sie die Dateigröße, indem Sie ausführen ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print %5}'
  • Ermitteln Sie die Größe der Tabelle aus Sicht des Informationsschemas: SELECT data_length+index_length FROM information_schema.tables WHERE table_schema='mydb' AND table_name='mytable';
  • Wenn dies der filesize > (data_length+index_length) * 1.1Fall ist, sollten Sie die Tabelle folgendermaßen ziehen:ALTER TABLE mydb.mytable ENGINE=InnoDB;

Dadurch wird eine temporäre Tabelle erstellt, nur echte Datenseiten und Indexseiten in die temporäre Tabelle kopiert, das Original gelöscht und die temporäre Tabelle wieder in mydb.mytable umbenannt. Sofortige Tabellenkomprimierung mit einem Befehl. Bitte planen Sie alle Tischkompressionen außerhalb der Geschäftszeiten.

RolandoMySQLDBA
quelle
@ RolandoMySQLDBA. Ich habe festgestellt, dass die Spalten Datengröße, Indexgröße und freier Speicherplatz nicht immer mit der Größe der Tabellendatei übereinstimmen .idb. Ich habe festgestellt, dass die Summe dieser Spalten fast immer kleiner ist als die tatsächliche .idbDatei - bis zu 33% kleiner. Gibt es eine andere Spalte, die mir fehlt? Wenn ich mir Ihre Anfrage oben ansehe, sehe ich, dass Sie nur Datengröße und Indexgröße verwenden.
John Rocha
Wenn data_length + index_length erheblich kleiner als die tatsächliche .ibdDatei ist, ist die .ibdDatei der perfekte Kandidat für die Defragmentierung. Ich füge das meiner Antwort hinzu.
RolandoMySQLDBA
Ich habe gerade meine Antwort aktualisiert !!!
RolandoMySQLDBA
Ich habe sowohl OPTIMIZE als auch ANALYZE auf einem 849-MB-Tisch ausgeführt und es ist nach OPTIMIZE auf 894 MB gesprungen. Es scheint, als hätte dies überhaupt nicht funktioniert und es noch schlimmer gemacht
NaturalBornCamper
3

MyISAM weist der Festplatte den tatsächlich genutzten Speicherplatz zu. Wenn Sie keine Fremdschlüssel, Transaktionen oder andere für InnoDB spezifische Funktionen verwenden, können Sie diese problemlos in MyISAM konvertieren. InnoDB ist schneller zum Schreiben und MyISAM ist schneller zum Lesen. Letztendlich würde ich empfehlen, die Unterschiede zwischen den Engines im Detail zu untersuchen, bevor die Speicher-Engines willkürlich geändert werden.

Hier ist eine Prozedur, die ich in der Vergangenheit zum Freigeben von InnoDB-Tabellenbereichen verwendet habe:

Löschen großer Datenmengen aus MySQL Innodb

Warner
quelle