it-swarm.com.de

InnoDB-Tabellenfehler erstellen: "Zeilengröße zu groß"

Wir haben einige Ingenieure, die eine normalisierte Datenbankstruktur in eine temporäre Tabelle reduzieren, um einen Bericht zu erstellen. Die Spalten werden als TEXT NOT NULL Angegeben (ich weiß, "warum machen sie das?"; Nehmen wir einfach an, wir sprechen dies an).

Wir verwenden MySQL 5.1.48 Community RHEL5 mit dem InnoDB Plug-In 1.0.9 unter Linux.

Bei der Verwendung von MyISAM sind wir nie auf Tabellengrößenbeschränkungen für maximale Spalten oder maximale Zeilenlänge gestoßen (während der Untersuchung haben wir die maximale Spaltenbeschränkung bei 2598 erreicht (die 2599. verursacht Fehler 1117). Mit InnoDB stoßen wir auf Grenzwerte. Diese Grenzwerte manifestieren sich beim Erstellen der Tabelle (keine Dateneinfügung) als:

FEHLER 1118 (42000) in Zeile 1: Zeilengröße zu groß. Die maximale Zeilengröße für den verwendeten Tabellentyp ohne BLOBs beträgt 8126. Sie müssen einige Spalten in TEXT oder BLOBs ändern

Ich suche nach Antworten auf Folgendes:

  1. Wie lautet die detaillierte Formel zur Bestimmung der Zeilengröße, insbesondere bei Verwendung von Partien mit v/v/b/t-Spalten? Ich habe einige verschiedene Formulare ausprobiert, indem ich varchar(N) - Spalten (wobei N zwischen 1 und 512 liegt), den UTF8-Zeichensatz (* 3) und so viele Spalten verwendet habe, wie die Tabelle bis zum Fehler benötigt. Keine der von mir versuchten Kombinationen liefert Werte, die mit den tatsächlichen Testergebnissen übereinstimmen.

  2. Welchen anderen Overhead muss ich bei der Berechnung der Zeilengröße berücksichtigen?

  3. Warum ändert sich die Fehlermeldung von 8126 auf 65535, wenn ich von der Erstellung von Tabellen mit varchar (109) -Spalten zu varchar (110) -Spalten übergehe?

11
Evan

Die Antworten auf Ihre Fragen sind komplex, da sie je nach InnoDB Dateiformat variieren. Heute gibt es zwei Formate, Antelope und Barracuda.

Die zentrale Tablespace-Datei (ibdata1) hat immer das Format Antelope . Wenn Sie Datei pro Tabelle verwenden, können Sie die einzelnen Dateien im Format Barracuda verwenden, indem Sie in my.cnf innodb_file_format=Barracuda Setzen.

Grundlegende Punkte:

  • Eine 16-KB-Seite mit InnoDB-Daten muss mindestens zwei Datenzeilen enthalten. Außerdem hat jede Seite eine Kopf- und Fußzeile mit Seitenprüfsummen, Protokollsequenznummer usw. Hier erhalten Sie ein Limit von etwas weniger als 8 KB pro Zeile.

  • Datentypen mit fester Größe wie INTEGER, DATE, FLOAT, CHAR werden auf dieser primären Datenseite gespeichert und zählen zur Beschränkung der Zeilengröße.

  • Datentypen mit variabler Größe wie VARCHAR, TEXT, BLOB werden auf Überlaufseiten gespeichert, sodass sie nicht vollständig für die Zeilengrößenbeschränkung berücksichtigt werden. In Antelope werden zusätzlich zur Speicherung auf der Überlaufseite bis zu 768 Byte solcher Spalten auf der Primärdatenseite gespeichert. Barracuda unterstützt ein dynamisches Zeilenformat , sodass möglicherweise nur ein 20-Byte-Zeiger auf der Primärdatenseite gespeichert wird.

  • Datentypen mit variabler Größe werden außerdem 1 oder mehr Bytes vorangestellt, um die Länge zu codieren. Das InnoDB-Zeilenformat verfügt auch über eine Reihe von Feldversätzen. Es gibt also eine interne Struktur mehr oder weniger dokumentiert in ihrem Wiki . [EDIT] Dead Link - hier sieht jetzt besser aus.

Barracuda unterstützt auch ein ROW_FORMAT = COMPRESSED , um die Speichereffizienz für Überlaufdaten zu erhöhen.

Ich muss auch kommentieren, dass ich noch nie gesehen habe, dass eine gut gestaltete Tabelle die Zeilengrößenbeschränkung überschreitet. Es ist ein starker "Code-Geruch", dass Sie die sich wiederholende Gruppen Bedingung der ersten Normalform verletzen.

19
Bill Karwin

Meine Situation ist etwas anders. Eines der Datenelemente, die ich in jeder Zeile speichern muss, ist möglicherweise sehr groß. (Das Datenfeld ist ein LONGBLOB für ein Dokument, das möglicherweise mehrere eingebettete Bilder enthält. Meine Beispieldatenbank enthält Dokumente mit einer Größe von 25 bis 30 MB, diese Dokumente können jedoch in einigen Fällen größer sein.) Keine der online gefundenen Lösungen hat Abhilfe geschaffen . (Der InnoDB-Dateityp wurde in Barracuda geändert, die Größe der Protokolldatei wurde erhöht und das Zeilenformat auf KOMPRESSIERT gesetzt.)

Die einzige Lösung, die sich für mich bewährt hat, war die Rückkehr zu MySQL 5.5.x von MySQL 5.6.x.

1
David