Was ist der beste Weg, um die Größe von ibdata in MySQL zu reduzieren?


63

Ich habe einige Produktionsserver, deren ibdataDateien von Tag zu Tag größer werden.

Es hat bereits 290 GB Speicherplatz verbraucht.

Die Tabellen in den Servern sind meist InnoDB und es gibt hohe Lese- und Schreibanforderungen.

Die Größe der Protokolldatei nimmt ebenfalls zu. Die Tabellen enthalten eine große Datenmenge.

Wie kann ich die wachsende Größe von beiden steuern?

Ich benutze nicht innodb_file_per_table.

Antworten:


104

Beachten Sie, dass die am stärksten ausgelastete Datei in der InnoDB-Infrastruktur / var / lib / mysql / ibdata1 ist

Diese Datei enthält normalerweise viele Informationsklassen (wenn innodb_file_per_table 0 ist)

  • Tabellendaten
  • Tabellenindizes
  • MVCC-Daten (Multiversioning Concurrency Control)
    • Rollbacks-Segmente
    • Tablespace rückgängig machen
  • Tabellen-Metadaten
  • Siehe Bilddarstellung

Viele Benutzer erstellen mehrere ibdata-Dateien in der Hoffnung auf eine bessere Verwaltung und Leistung des Speicherplatzes. Es hilft nicht.

Leider führt OPTIMIZE TABLE für eine in ibdata1 gespeicherte InnoDB-Tabelle zwei Aktionen aus:

  • Macht die Daten und Indizes der Tabelle in ibdata1 zusammenhängend
  • Dadurch wächst ibdata1, da die zusammenhängenden Daten an ibdata1 angehängt werden

Sie können Tabellendaten und Tabellenindizes von ibdata1 trennen und mithilfe von innodb_file_per_table unabhängig verwalten . Um ibdata1 ein für alle Mal zu verkleinern, müssen Sie Folgendes tun

Schritt 01) MySQLDump alle Datenbanken in eine SQL-Textdatei (nennen Sie es SQLData.sql) ( Weitere Details hier )

Schritt 02) Löschen Sie alle Datenbanken (außer mysql, performance_schemaund information_schema)

Schritt 03) Fahren Sie mysql herunter

Schritt 04) Fügen Sie die folgenden Zeilen zu /etc/my.cnf hinzu

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

Anmerkung: Unabhängig von Ihrer Einstellung für innodb_buffer_pool_size müssen Sie sicherstellen, dass innodb_log_file_size 25% von innodb_buffer_pool_size beträgt.

Schritt 05) Löschen Sie ibdata1, ib_logfile0 und ib_logfile1

Zu diesem Zeitpunkt sollte nur das MySQL-Schema in / var / lib / mysql vorhanden sein

Schritt 06) Starten Sie mysql neu

Dadurch wird ibdata1 bei 10 MB, ib_logfile0 und ib_logfile1 bei jeweils 1 GB neu erstellt

Schritt 07) Laden Sie SQLData.sql erneut in mysql

ibdata1 wächst, enthält jedoch nur Tabellenmetadaten

Jede InnoDB-Tabelle existiert außerhalb von ibdata1

Angenommen, Sie haben eine InnoDB-Tabelle mit dem Namen mydb.mytable. Wenn Sie in / var / lib / mysql / mydb gehen, sehen Sie zwei Dateien, die die Tabelle darstellen

  • mytable.frm (Speicher-Engine-Header)
  • mytable.ibd (Heimat von Tabellendaten und Tabellenindizes für mydb.mytable)

ibdata1 enthält nie mehr InnoDB-Daten und -Indizes.

Mit der Option innodb_file_per_table in /etc/my.cnf können Sie ausführen OPTIMIZE TABLE mydb.mytableund die Datei /var/lib/mysql/mydb/mytable.ibdwird tatsächlich verkleinert.

Ich habe dies in meiner Karriere als MySQL-DBA viele Male getan

Tatsächlich habe ich beim ersten Mal eine 50 GB große ibdata1-Datei auf 500 MB reduziert.

Versuche es. Wenn Sie weitere Fragen dazu haben, senden Sie mir eine E-Mail. Vertrau mir. Dies wird kurzfristig und langfristig funktionieren. !!!

Wenn Sie sehen möchten, wie viele aktuelle Daten in MyISAM und InnoDB gespeichert sind, führen Sie bitte diese Abfrage aus:

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;

Selbst mit den vorgeschlagenen Einstellungen für my.cnf (die ich bereits habe), dem Löschen von ib_logfile0 und 1 und dem anschließenden Starten von mysql, werden die neuen Dateien erstellt und innerhalb von Sekunden an die Größe der Datenbank angepasst, wie sie von Ihrer obigen Abfrage angezeigt wird. Ich bin mir nicht sicher, ob mysql alle Tabellen und Indizes in diese Dateien kopiert und gleichzeitig jede Tabelle in einer separaten Datei verwaltet.
Allen King
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.