it-swarm-eu.dev

MySql - Ändern von innodb_file_per_table für eine Live-Datenbank

Ich habe eine große MySQL-Datenbank (150 GB) und erst jetzt habe ich bemerkt, dass die innodb_file_per_table wird auf off gesetzt, wodurch die gesamte Datenbank in einer einzigen Datei gehostet wird (ibdata1). Ich möchte innodb_file_per_table und die Datenbank rückwirkend in mehrere Dateien aufteilen, wie geht das am besten?

19
Ran

Es gibt wirklich nur einen Weg, dies durchzuziehen. Sie müssen die Daten mit mysqldumps exportieren, alle Datenbanken löschen, mysqld herunterfahren, ib_logfile0 löschen, ib_logfile1 löschen, ibdata1 löschen, innodb_file_per_table Unter der Überschrift [mysqld] Hinzufügen und mysql starten.

Ich habe diese Antwort im Oktober 2010 in StackOverflow gepostet

Hier sind die vertikal aufgelisteten Schritte:

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

Schritt 02) Löschen Sie alle Datenbanken (außer dem MySQL-Schema).

Schritt 03) Herunterfahren von MySQL

[~ # ~] Einschränkung [~ # ~] : Führen Sie dies aus, um nicht festgeschriebene Transaktionen vollständig aus den InnoDB-Dateien zu entfernen

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop

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

Nebenbemerkung: Unabhängig von Ihrer Einstellung für innodb_buffer_pool_size stellen Sie sicher, 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 es nur das MySQL-Schema in/var/lib/mysql geben

Schritt 06) Starten Sie MySQL neu

Dadurch werden ibdata1 mit 10 MB, ib_logfile0 und ib_logfile1 mit 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, werden zwei Dateien angezeigt, die die Tabelle darstellen

  • mytable.frm (Storage Engine Header)
  • mytable.ibd (Startseite der Tabellendaten und Tabellenindizes für mydb.mytable)

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

Mit der Option innodb_file_per_table in /etc/my.cnf können Sie OPTIMIZE TABLE mydb.mytable ausführen, und die Datei /var/lib/mysql/mydb/mytable.ibd wird 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-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. !!!

Es gibt eine Alternative, die die InnoDB-Tabelle extrahiert, ohne ibdata1 zu verkleinern.

Schritt 01) 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

Schritt 02) service mysql restart

Schritt 03) Gehen Sie folgendermaßen vor, um eine einzelne InnoDB-Tabelle mit dem Namen mydb.mytable zu extrahieren:

ALTER TABLE mydb.mytable ENGINE=InnoDB;

Dadurch wird eine Datei erstellt. Pleus behält die ursprüngliche Strukturdatei bei

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

Sie können dies für jede InnoDB-Tabelle tun. Leider bleibt ibdata1 150 GB.

32
RolandoMySQLDBA

Wenn Sie den Speicherplatz von ibdata zurückfordern möchten, ist ein Dump/Restore Ihre einzige Wahl, wie Rolando hervorhebt. Es ist wahrscheinlich auch am besten für die Leistung, dies zu tun.

Wenn Sie jedoch nur Ihre Verluste reduzieren und diese 150 GB auf der Festplatte "verlieren" möchten, können Sie einfach innodb_file_per_table in der my.cnf und starten Sie Ihren Server neu.

Geben Sie dann für jede Tabelle Folgendes aus:

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

Das Problem hierbei ist, dass große Tablespaces eine Weile dauern werden.

Ich würde vorschlagen, einen Slave Ihrer Live-Datenbank einzurichten, die Konvertierung auf dem Slave auszuführen, dann entweder den Master/Slave auszuschalten und den neuen Datenbereich auf den Master zu kopieren oder den Slave zum Master zu befördern, sobald er aufgeholt hat .

Sie werden Schwierigkeiten haben, diese Änderung ohne Ausfallzeiten vorzunehmen.

5
Derek Downey