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

11

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

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 Grenzen. Diese Grenzen werden 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 mit varchar(N)Spalten (wobei N zwischen 1 und 512 liegt), dem UTF8-Zeichensatz (* 3) und so vielen Spalten ausprobiert, 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?


quelle
Ich hatte das gleiche Problem. Als ich eine Datenbank überprüfte, stellte ich fest, dass eines der Add-Ons zum Webbrowser HTML-Code in den Seitenquellcode (sogar in das Formular) einfügte, was das Problem verursachte.
HTML ist nicht der Bösewicht. Noch die Größe dieses HTML. Sie müssen mehrere Text- / Varchar-Spalten gehabt haben und einige Einschränkungen getroffen haben, die umgangen werden können.
Rick James

Antworten:

19

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) ist immer im Antelope- Format. Wenn Sie Datei pro Tabelle verwenden, können Sie die einzelnen Dateien im Barracuda- Format verwenden, indem Sie innodb_file_format=Barracudain my.cnf festlegen.

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, die mehr oder weniger in ihrem Wiki dokumentiert ist . [EDIT] Toter Link - hier sieht es jetzt besser aus.

Barracuda unterstützt auch 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 gegen die Bedingung der sich wiederholenden Gruppen der ersten Normalform verstoßen .

Bill Karwin
quelle
2
Für Ingenieure, die nicht DB-bewusst sind, ist es sehr einfach, den Flat-Data-Weg zu gehen. es führt NIEMALS durch. Meine eigene Legacy-DB, die eine ähnliche Situation hat, trifft die Zeilengröße nicht so dramatisch, aber Junge, es ist ein Leistungssegen! Ich würde sagen, Ihr Reporting Engineer muss akzeptieren, dass er Joins durchführen und diese Arbeit mit der gesamten Indizierung gut wettmachen muss.
TechieGurl
1

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 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.

David
quelle