Warum innodb_file_per_table verwenden?

26

Es gibt viele Artikel, die (meiner Meinung nach natürlich) die Notwendigkeit für übertreiben innodb_file_per_table. Ich verstehe, dass es mit innodb_file_per_tableeine bessere Kontrolle über die einzelnen Tabellen geben sollte; wie Backup jeder Tabelle separat. Der Anspruch auf bessere Leistung ist jedoch fraglich.

In meinem Test gibt es keinen Unterschied in der Leistung von innodb_file_per_tableund ibdata1für eine Datenbank von 60 GB. Natürlich war es ein einfacher Test mit normalen Abfragen, und die Situation kann für komplizierte Abfragen im wirklichen Leben anders sein (dies ist der Grund, warum ich diese Frage gestellt habe). 64-Bit-Linux mit ext4kann effektiv mit großen Dateien umgehen.

Mit innodb_file_per_tablewerden mehr Platten-E / A-Operationen benötigt; und dies ist in komplizierten JOINs und FOREIGN KEYEinschränkungen von Bedeutung.

Der Tablespace wird auf Single geteilt ibdata. Wie können dedizierte Tablespaces für separate Tabellen Speicherplatz sparen? Natürlich ist es einfacher, Tabellenplatz für jede Tabelle freizugeben ALTER, aber es ist immer noch ein teurer Prozess (mit Tabellensperre).

FRAGE: Hat dies innodb_file_per_tableAuswirkungen auf eine bessere Leistung von MySQL? Wenn ja warum

Googlebot
quelle
Siehe diese Antwort auf meine Frage: dba.stackexchange.com/questions/7924/… könnte ebenfalls helfen.
KM.

Antworten:

19

Ich denke nicht, dass es um Leistung geht, sondern um Management.

Mit einer separaten Datei pro Tabelle können Sie beispielsweise verschiedene Datenbanken auf verschiedenen Speichergeräten speichern.

Sie können den Fall sehr großer Datenbanken in Dateisystemen behandeln, die keine großen Dateien verarbeiten können (verschieben Sie das Problem zumindest, bis eine Tabelle die maximale Dateigröße erreicht hat).

Sie haben kein unkontrolliertes Tablespace-Wachstum. Wenn Sie einige große Tabellen löschen, ibdatableibt die Datei klein.

Ein Aspekt, der sich auf die Leistung auswirken kann, ist die Fragmentierung von Tabellendaten und Indizes, die pro Tabelle begrenzt wird. Aber das muss getestet werden, um bestätigt zu werden.

ypercubeᵀᴹ
quelle
Das Tablespace-Wachstum ist genau der Grund, warum Sie möchten innodb_file_per_table.
Sjas
13

Warum innodb_file_per_table verwenden?

Weil es einfacher ist, einzelne Dateien zu verwalten, da dies auf Dateiebene möglich ist. Dies bedeutet, dass Sie auch dann Daten kopieren können, wenn der Server ausfällt, indem Sie die Tabellendateien kopieren. Wenn Sie einen gemeinsam genutzten Tabellenbereich verwenden, müssen Sie entweder alles kopieren, was unnötig umfangreich sein kann, oder einen Weg finden, den Server zum Extrahieren von Daten zum Laufen zu bringen ( Sie möchten die Daten wirklich nicht manuell mit einem Hex-Editor extrahieren.

Jemand hat gewarnt, dass Sie .ibdDateien nicht einfach von einem Server auf einen anderen kopieren und einfügen können. Dies mag zutreffen, sollte aber nicht für Backups auf demselben Server gelten (ich verwende den Begriff Backup hier im herkömmlichen Sinne, um eine Kopie zu erstellen, dh das Ganze nicht drastisch zu ändern). Darüber hinaus ibdata1wird beim Start automatisch neu erstellt (wie im Löschschrittibdata1 der meisten Handbücher zum Konvertieren in Dateien pro Tabelle zu sehen). Daher müssen Sie nichtibdata1 zusätzlich zu Ihren .ibdDateien (und den entsprechenden .frmDateien usw.) kopieren .

Wenn Sie versuchen, eine verlorene Tabelle wiederherzustellen, sollte es ausreichend sein, ihre .ibdund die .frmDatei sowie information_schema(die viel kleiner ist als ibdata1) zu kopieren . Auf diese Weise können Sie sie in einen Dummy-Server einfügen und Ihre Tabelle extrahieren, ohne das ganze, massive Ding kopieren zu müssen.

Der Anspruch auf bessere Leistung ist jedoch fraglich. … Mit innodb_file_per_table werden mehr Platten-E / A-Operationen benötigt. Dies ist bei komplizierten JOINs und FOREIGN KEY-Einschränkungen von Bedeutung.

Es überrascht nicht, dass die Leistung vollständig von den verwendeten Datenbanken abhängt. Eine Person wird (sogar sehr) unterschiedliche Ergebnisse von einer anderen haben.

Es ist wahr, dass es mit file-per-table mehr Platten-E / A-Operationen geben wird, aber nur geringfügig mehr. Überlegen Sie, wie das System funktioniert.

  • Für eine monolithische Datenbank:

    1. Server wird gestartet
    2. ibdata1 ist geöffnet
    3. Header und Metadaten werden gelesen
    4. Strukturen und Metadaten werden im Speicher zwischengespeichert
    5. Abfragen passieren
      1. Der Server greift auf die Festplatte zu und liest die Daten von der bereits geöffneten ibdata1
      2. Möglicherweise speichert der Server die Daten im Speicher
  • Für eine Datenbank pro Tabelle:

    1. Server wird gestartet
    2. ibdata1 ist geöffnet
    3. Header und Metadaten werden gelesen
    4. Jede einzelne .ibdDatei wird geöffnet
    5. Kopf- und Metadaten werden aus jeder .ibdDatei gelesen
    6. Strukturen und Metadaten werden im Speicher zwischengespeichert
    7. Abfragen passieren
      1. Der Server greift auf die Festplatte zu und liest die Daten aus der bereits geöffneten .ibdDatei
      2. Möglicherweise speichert der Server die Daten im Speicher

Sie werden feststellen, dass Sie die Datendateien nicht verschieben können, wenn der Server ausgeführt wird, da der Server über offene Punkte für sie verfügt. Dies liegt daran, dass sie beim Starten geöffnet und geöffnet bleiben. Sie werden nicht für jede einzelne Abfrage geöffnet und geschlossen.

Daher gibt es zu Beginn des Serverstarts nur noch einige weitere E / A-Vorgänge. nicht während es läuft. Während jede einzelne .ibdDatei ihren eigenen Overhead hat (Dateisignaturen, Strukturen usw.), werden sie im Arbeitsspeicher zwischengespeichert und nicht für jede Abfrage erneut gelesen. Darüber hinaus werden dieselben Strukturen auch mit einem gemeinsam genutzten Tabellenbereich gelesen, sodass kaum (wenn überhaupt) mehr Speicher benötigt wird.

Hat innodb_file_per_table einen Einfluss auf eine bessere Leistung von MySQL?

Eigentlich, wenn überhaupt, die Leistung kann in der Tat sein schlechter .

Bei Verwendung eines gemeinsam genutzten Tabellenbereichs können Lese- und Schreibvorgänge manchmal / oft kombiniert werden, sodass der Server ein Datenfeld aus mehreren Tabellen auf einmal liest ibdata.

Wenn die Daten jedoch auf mehrere Dateien verteilt sind, muss für jede Datei eine separate E / A-Operation ausgeführt werden.

Dies hängt natürlich wieder vollständig von der betreffenden Datenbank ab. Die tatsächlichen Auswirkungen auf die Leistung hängen von der Größe, der Häufigkeit der Abfragen und der internen Fragmentierung des gemeinsam genutzten Tabellenbereichs ab. Einige Menschen bemerken möglicherweise einen großen Unterschied, während andere möglicherweise überhaupt keine Auswirkungen sehen.

Der Tablespace wird auf einzelnen ibdata gemeinsam genutzt. Wie können dedizierte Tablespaces für separate Tabellen Speicherplatz sparen?

Es tut nicht. Wenn überhaupt, erhöht es die Festplattennutzung um einiges.

Ich habe keine 60-GB-Datenbank zum Testen, aber meine „dürftige“ persönliche Datenbank, die meine WordPress-Installation und einige kleine Tabellen für den persönlichen Gebrauch und Entwicklungstests enthält, wog bei Verwendung eines gemeinsam genutzten Tabellenbereichs etwa 30 MB. Nachdem es in eine Datei pro Tabelle konvertiert wurde, hatte es eine Größe von ~ 85 MB. Selbst wenn alles gelöscht und erneut importiert wurde, waren es immer noch> 60 MB.

Dieser Anstieg ist auf zwei Faktoren zurückzuführen:

  • Die absolute Mindestgröße für ibdata1beträgt - aus irgendeinem Grund - 10 MB, auch wenn nichts anderes information_schemagespeichert ist.

  • Bei einem gemeinsam genutzten Tabellenbereich ist nur ibdata1der Overhead wie Dateisignaturen, Metadaten usw. vorhanden. Bei einer tabellenspezifischen .ibdKonfiguration hat jede einzelne Datei all dies. Dies bedeutet, dass die Summe (auch bei einem hypothetischen Wert <10 MB ibdata1) um mindestens Folgendes etwas größer wäre:

    GetTotalSizeofOverhead() * GetNumTables()

Offensichtlich sind dies keine gewaltigen Zuwächse (es sei denn, Sie verwenden einen Host, der die Größe Ihrer Datenbank einschränkt, oder Sie speichern sie auf einem Flash-Laufwerk usw.), aber sie nehmen trotzdem zu, und zwar indem Sie ( jede ) Tabelle in eine Datei umwandeln -pro-Tabelle können ibdata1Sie auf 10 MB verkleinern, die Gesamtsumme wird immer mehr als es war.

Synetech
quelle
11

Dies ist mein Grund, warum ich IMMER innodb_file_per_table benutze:

Ohne Datei pro Tabelle wird die ibdata-Datei niemals komprimiert, verkleinert oder verkleinert. Nicht, wenn Sie eine Zeile, eine Tabelle oder eine Datenbank löschen. 2 GB Daten können in kürzester Zeit zu einer 20 GB großen Datei werden, wenn Sie ein aktives Warteschlangensystem haben.

Angenommen, Sie möchten vor einer Änderung eine Sicherungskopie Ihrer aktuellen 1-GB-Tabelle erstellen und diese anschließend löschen. In Ihren ibdata stecken Sie mit einem GB ungenutzten Speicherplatz fest. Schade.

Es gibt wahrscheinlich endlose Beispiele für Fälle, in denen temporäre Maßnahmen die einzelne Datendatei aufblasen, aber meiner Meinung nach gibt es keinen Grund, innodb_file_per_table NICHT zu verwenden

Hier ist auch ein guter Beitrag zum Lesen: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table

randomx
quelle
1
Mir wurde klar, dass es IMMER gut ist, es auch zu tun. Magnetische Speicher-Arrays, die von SSDs unterstützt werden, können Lese- / Schreib-Caches für kleinere Dateien für Tabellen effektiver verarbeiten. Für eine Reihe von Tabellen, die in% 99,99 Fällen nur gelesen, aber nicht geschrieben werden, befinden sie sich immer im Cache des Speichercontrollers, was die Antwortzeit erheblich verkürzt.
SDKKS
5

Mein Grund, warum ich innodb_file_per_table nicht verwende, ist die Leistung.

Ich habe einige Tests für unsere Datenbank mit 450 Tabellen unter mysql 5.5.45 Linux CentOS Release 6.7 durchgeführt

Bei Komponententests , bei denen Fixtures vor jedem Test in die Datenbank eingefügt werden (wobei nicht jedes Mal alle Tabellen verwendet werden), und bei Tests selbst, die häufig mit der Datenbank ausgeführt werden ( Einfügen , Aktualisieren, Löschen, Auswählen ), war die Leistung 3-5x besser, als bei Datenbanktabellen in weitere Dateien aufgeteilt.

Ich empfehle, Ihre Datenbank mit Abfragen zu testen, die Sie verwenden möchten, und sie zu vergleichen, bevor Sie sich für die Verwendung von innodb_file_per_table entscheiden

Vielleicht können Sie herausfinden, dass Sie für den Produktionsserver innodb_file_per_table verwenden können, aber für die CI-Umgebung (setzt die Integration fort), die Unit-Tests startet (verwendet häufig DB), und auch für Entwickler, die Unit-Tests häufig starten, ist es aufgrund der Leistung besser, sie nicht zu verwenden.

Tomor
quelle
2
Ich vermute, dies liegt an der Zeit, die erforderlich ist, um die anfänglichen Dateien für alle 450 Tabellen zuzuweisen, im Gegensatz zur Zuweisung einer einzelnen Datei. In der Produktion wird dies nur einmal vorkommen, es sollte also kein Problem sein. Sie machen jedoch darauf aufmerksam, dass es besser ist, eine Datenbank schnell zu erstellen, sie dann vollständig herunterzufahren und immer wieder eine einzelne ibdata-Datei zu wiederholen.
ColinM
2

Dadurch werden die Daten einfacher zu verwalten, da Sie nicht genutzten Speicherplatz zurückfordern können.

Ich denke, wenn Ihre Datenbank hauptsächlich für ausgewählte Abfragen verwendet wird, hat dies keinen großen Einfluss auf die Leistung. Es muss immer noch ungefähr die gleiche Datenmenge lesen. Ich denke nicht, dass es wichtig ist, aus welchen Dateien die Daten gelesen werden.

Dies kann jedoch die Leistung einer Datenbank beeinträchtigen, die viele Einfügungen und Aktualisierungen vornimmt. Dies liegt daran, dass mysql fsync () für die Speicherdatei aufruft, nachdem Sie eine Transaktion festgeschrieben haben. Wenn es eine einzelne Datei gibt, wird ein Anruf getätigt und auf den Abschluss des Anrufs gewartet. Wenn es viele Dateien gibt, muss der Aufruf mehrmals erfolgen und auf die Rückkehr aller Aufrufe warten, bevor der Festschreibungsbefehl zurückgegeben werden kann.

Hier ist ein Beitrag von jemandem, bei dem dieses Problem aufgetreten ist : http://umangg.blogspot.com/2010/02/innodbfilepertable.html

Sarel Botha
quelle
2

Gemäß dem folgenden Artikel geht es bei der Leistung nicht um das Verwalten von Daten (Rohoperationen selbst), sondern um das Erstellen und Löschen von Objekten.

innodb_file_per_table verlangsamt die massive Erstellung und das Ablegen von Objekten als ibdata-Speicher und ist für die Produktion nicht anwendbar, sollte aber für kontinuierliche Tests relevant sein.

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/

Flavio Peinado
quelle