MySQL InnoDB - innodb_file_per_table Nachteile?


32

Standardmäßig speichert MySQL InnoDB alle Tabellen aller DBs in einer globalen Datei. Sie können dies ändern, indem Sie innodb_file_per_table in der Konfiguration festlegen, die dann eine Datendatei für jede Tabelle erstellt.

Ich frage mich, warum innodb_file_per_tablenicht standardmäßig aktiviert ist. Gibt es Nachteile bei der Verwendung?

Antworten:


32

Ich habe die vollständige Antwort auf diese Frage.

Sobald innodb_file_per_table eingerichtet ist und neue InnoDB-Tabellen mit verkleinert werden können, ALTER TABLE <innodb-table-name> ENGINE=InnoDB';werden neue .ibdDateien mit GARANTIE verkleinert.

Wenn Sie ALTER TABLE <innodb-table-name> ENGINE=InnoDB';eine InnoDB-Tabelle ausführen, die vor der Verwendung von innodb_file_per_table erstellt wurde, werden die Daten und Indizes für diese Tabelle aus der Datei ibdata1 entfernt und in einer .ibdDatei gespeichert. Auf diese Weise verbleibt eine permanente Taube in der Datei ibdata1, die niemals wiederverwendet werden kann .

Die ibdata1Datei enthält normalerweise vier Arten von Informationen

  • Tabellendaten
  • Tabellenindizes
  • MVCC- Daten (Multiversioning Concurrency Control)
    • Rollback-Segmente
    • Leerzeichen rückgängig machen
  • Tabellenmetadaten (Data Dictionary)
  • Double Write Buffer (Hintergrundschreiben, um das Caching des Betriebssystems zu verhindern)
  • Insert Buffer (Verwalten von Änderungen an nicht eindeutigen Sekundärindizes)
  • Siehe die Pictorial Representation of ibdata1

Hier ist die garantierte Möglichkeit, die ibdata1-Datei für immer zu verkleinern ...

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

SCHRITT 02) Löschen Sie alle Datenbanken (mit Ausnahme der Schemata mysql, information_schema und performance_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
innodb_data_file_path=ibdata1:10M:autoextend

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 ( siehe Update unten vor dem Löschen! )

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 neu erstellt (Option nicht konfigurieren), ib_logfile0 und ib_logfile1 bei jeweils 1 GB

  • SCHRITT 07) Laden Sie SQLData.sql erneut in mysql

ibdata1 wächst, enthält jedoch nur Tabellenmetadaten und intermittierende MVCC-Daten.

Jede InnoDB-Tabelle existiert außerhalb von ibdata1

Angenommen, Sie haben eine InnoDB-Tabelle mit dem Namen mydb.mytable. Wenn Sie darauf zugreifen /var/lib/mysql/mydb, werden zwei Dateien angezeigt, die die Tabelle darstellen

  • mytable.frm (Speicher-Engine-Header)
  • mytable.ibd(Heimat 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.cnfkönnen Sie OPTIMIZE TABLE mydb.mytableOR ausführen ALTER TABLE mydb.mytable ENGINE=InnoDB;und die Datei /var/lib/mysql/mydb/mytable.ibdwird tatsächlich verkleinert.

Ich habe dies in meiner Karriere als MySQL-DBA unzählige Male getan, ohne danach ein einziges Problem zu haben. Tatsächlich habe ich beim ersten Mal eine 50 GB große ibdata1-Datei auf 50 MB reduziert.

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

UPDATE 2013-07-02 15:08 EDT

Ich habe diesbezüglich eine Einschränkung, die ich in anderen Beiträgen von mir aktualisiert habe, aber diese habe ich verpasst: Ich aktualisiere meine Antwort ein wenig mehr mit innodb_fast_shutdown, weil ich mysql neu gestartet und mysql dazu angehalten habe. Jetzt ist dieser Schritt von entscheidender Bedeutung, da jede nicht festgeschriebene Transaktion andere bewegliche Teile innerhalb und außerhalb der InnoDB-Transaktionsprotokolle enthalten kann ( siehe InnoDB-Infrastruktur ).

Bitte beachten Sie, dass das Setzen von innodb_fast_shutdown auf 2 die Abmeldungen ebenfalls bereinigen würde, aber noch mehr bewegliche Teile vorhanden sind und bei Crash Recovery während des Starts von mysqld ausgewählt werden. Die Einstellung 0 ist am besten.


Tolle Infos - danke! 50 GB >> 50 MB - das ist ziemlich beeindruckend!
UpTheCreek

Hallo, ich habe versucht, genau das zu tun, was Sie hier geschrieben haben. Das "einzige" Problem ist, dass der Server danach nicht mehr startet. Wenn ich Mysql starte, hängt es einfach dort. Wenn ich meine alte CNF-Datei zurückschalte, ist alles in Ordnung. Hast du eine Ahnung davon?
Nicola Peluchetti

Diese Frage ist für Nicola: Hast du Schritt 5 gemacht ???
RolandoMySQLDBA

Noch eine Frage an @Nicola: Wie viel RAM hast du in deinem System ???
RolandoMySQLDBA

2
Achtung! Die Option innodb_fast_shutdown=0muss vor dem Herunterfahren in MySQL gesetzt werden, um die Protokolldateien zu löschen! ( ib_logfile0und ib_logfile1) Andernfalls könnten Sie Daten verlieren!
Totor

12

Siehe Fehler .

Gibt es Nachteile bei der Verwendung?

  • mehr offene Dateien
  • Overhead öffnen / wieder öffnen
  • .ibd-Datei wird nicht verkleinert (siehe 1 , 2 )

Bei großen Datenbanken verwende ich immer innodb_file_per_table.


Auch wenn Sie es nicht verwenden, werden ibdata-Dateien nicht verkleinert :(
minaev

1
Vielen Dank. Ich frage mich auch, warum es keine Option gibt, eine Datei pro Datenbank zu haben.
UpTheCreek

1
@UpTheCreek, Tabellen sind Entitäten. Datenbanken sind logische Gruppen von Entitäten und keine eigenständigen Entitäten. Bei MyISAM ist es offensichtlicher, dass Datenbanken Verzeichnisse und Tabellen Dateien sind.
John Gardeniers

Ich wollte nur darauf hinweisen, dass .ibd-Dateien zwar nicht automatisch verkleinert werden , aber auch nicht ibdata1die Alternative zu file-per-table. Zumindest ist es möglich, eine .ibd mit zu verkleinern optimize table, was im Vergleich zum Verkleinern von ibdata1 trivial ist.
RomanSt

8

innodb_file_per_table ist in MariaDB standardmäßig aktiviert.


1
Nicht in meinem (die Standardversion in CentOS 7). Sie benötigen das Äquivalent von MySQL 5.6.6 oder neuer. Andernfalls ist die Standardeinstellung deaktiviert .
Leichtigkeit Rennen mit Monica

2

Der Grund, warum ich mich gegen die Verwendung entschieden habe innodb_file_per_table, ist, dass jede Tabelle in einer eigenen Datei abgelegt ist, was bedeutet, dass jede Tabelle ihren eigenen, separaten Overhead (Dateisignaturen usw.) erhält, wodurch sich die Gesamtgröße des MySQLVerzeichnisses ergibt größer als bei Verwendung eines gemeinsam genutzten Tabellenbereichs. Darüber hinaus wird aufgrund der Cluster-Lose mehr Speicherplatz verschwendet, wenn mehrere kleine Dateien statt einer einzigen großen vorhanden sind.

Zugegeben, der zusätzliche Aufwand ist im großen Rahmen nicht gewaltig , insbesondere wenn Sie ein großes Laufwerk verwenden oder eine riesige Datenbank haben, aber für mich selbst (und wahrscheinlich für viele „Heimanwender“) summiert sich alles auf und war immer noch zu viel für das kleine Laufwerk mit den großen Clustern, in denen ich meinen MySQL-Speicher aufbewahrte.

Zum Beispiel meine Datenbankspeicher mit meinem Wordpress - Datenbanken und ein paar andere kleine Datenbanken (phpBB, Entwickler, einige AMP - Tests, etc.), die Umstellung auf pro-Tabelle änderte sie sich von 32 MB bis 50 MB, und das schließt nicht einmal die ibdata1denen noch erfordert ein Minimum von 10 MB , für eine Gesamtmenge von mindestens 60 MB.

Wie ich bereits sagte, ist dies für manche Menschen, insbesondere für Unternehmen, kein allzu großes Problem. Wenn Sie jedoch ein Heimanwender sind, der nur Ihre Website, Ihren Blog usw. hostet, kann dies in der Tat ein Faktor bei der Auswahl sein ein Host-Provider, weil viele Hosts die Größe Ihrer Datenbank zusätzlich zur gesamten Festplattennutzung begrenzen.


1
Ich dachte, du wärst verrückt (wen interessieren zehn Megabyte ???), bis du den Punkt über enge Quoten bei Hosting-Anbietern verstanden hast. Daran hätte ich nie gedacht.
Dan Pritts

@ DanPritts, vor allem kostenlose Hosts. Außerdem haben Sie vielleicht einen riesigen Antrieb, aber nicht jeder hat einen. Ich habe meine Hauptdatenpartition im letzten Jahr von 1 GB auf 2 GB erweitert, weil sie zu eng war, aber selbst 10 MB hier und 10 MB dort (insbesondere bei Protokolldateien) können sie schnell aufzehren. Vergessen Sie nicht, dass sich auch Cluster-Abfall summiert. Schließlich ist es nicht unbedingt eine Festplatte . Zum Beispiel „portiere“ ich derzeit meine Website, damit ich sie von jedem System aus hosten kann, sodass ein 2-GB-Flash-Laufwerk bereits eingeschränkt ist. Daher ist es wichtig, die Größe klein zu halten und Schreibvorgänge zu vermeiden. Und dann gibt es eingebettete Systeme!
Synetech

Plus, es ist nicht 10 MB (das ist die absolute Mindestgröße für IBDATA1). Es ging von 30 MB auf ~ 85 MB. Nachdem ich das Ganze gelöscht und einen Dump von Grund auf neu importiert hatte, erhielt ich 69 MB anstelle der vorherigen 30 MB (eine Vermutung, welche Datenbank mehr als die Hälfte davon in Anspruch nahm). Aus irgendeinem Grund sind meine ibdata1Daten trotz der Verwendung pro Tabelle immer noch 18 MB groß. ☹
Synetech

Klingt eher nach etwas, das ich mit einer CMS-Installation mit vs. einer ohne Selinux-Aktivierung hatte, gemessen an den Dateigrößen von 32M vs. 50M. Ich kann die Zahlen nicht wirklich glauben, wie viele Datenbanken haben Sie überhaupt, dass sich die Metadaten einiger Dateien auf ansonsten identischen Systemen zu MEGABYTES summieren können?
So

2

Nur um ein bisschen mehr Infos hinzuzufügen

Seit MySQL 5.6.6 ist es standardmäßig aktiviert


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.