Zeilengrößenfehler mit MySQL

11

Ich verwende einen MySQL-Server auf meinem Macbook (zum Testen). Version ist 5.6.20 von Homebrew. Ich habe angefangen, Fehler "Zeilengröße zu groß" zu finden, und ich konnte sie auf diesen Testfall reduzieren. Tabelle:

mysql> describe test;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| stuff | longtext | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+

Tabellenstatus:

mysql> show table status where Name = 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| test | InnoDB |      10 | Compact    |    1 |          16384 |       16384 |               0 |            0 |   5242880 |              2 | 2014-08-28 23:51:12 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+

Der Fehler wird stuffangezeigt , wenn ich versuche, eine Zeile in die Tabelle einzufügen, in der die Spalte mehr als 5033932 Byte enthält.

mysql> select length(stuff) from test;
+---------------+
| length(stuff) |
+---------------+
|       5033932 |
+---------------+

mysql> update test set stuff = concat(stuff, 'a');
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.

Ich habe nach diesem Fehler gesucht. Die meisten Antworten beinhalten zu viele TEXT-Spalten, und in jeder sind 768 Bytes inline gespeichert. Wie Sie sehen, ist das bei mir nicht der Fall. Außerdem bleibt die Nummer 5033932 unabhängig von der Anzahl der Spalten in der Tabelle gleich. In meiner ursprünglichen Anwendung gab es fünf Spalten, und die Aktualisierungen schlugen immer noch fehl, wenn die Spaltengröße 5033932 überschritt.

Ich habe auch Leute gesehen, die das Problem durch Wechseln der Zeilenformate gelöst haben, was ich gleich versuchen werde, aber ich möchte genau verstehen, was diesen Fehler verursacht.

Danke im Voraus!

geoffliu
quelle

Antworten:

12

Eine Änderung in den Versionshinweisen zu 5.6.20:

Redo-Log-Schreibvorgänge für große, extern gespeicherte BLOB-Felder können den letzten Prüfpunkt überschreiben. Der Patch 5.6.20 begrenzt die Größe der Redo-Log-BLOB-Schreibvorgänge auf 10% der Größe der Redo-Log-Datei. Der Patch 5.7.5 behebt den Fehler, ohne eine Einschränkung aufzuerlegen. Für MySQL 5.5 bleibt der Fehler eine bekannte Einschränkung.

Aufgrund des für MySQL 5.6 eingeführten Redoblog-BLOB-Schreiblimits sollte innodb_log_file_size auf einen Wert festgelegt werden, der größer ist als das Zehnfache der größten BLOB-Datengröße in den Zeilen Ihrer Tabellen plus der Länge anderer Felder variabler Länge (VARCHAR, VARBINARY) und Felder vom Typ TEXT). Andernfalls können Fehler "Zeilengröße zu groß" auftreten.

(Hervorhebung von mir)

Der Standardwert für innodb_log_file_sizeist 50331648, was bedeutet, dass der größte BLOB / TEXT-Wert, den Sie unabhängig vom Datentyp erstellen können, nahe bei 5033164 liegt und Sie festgestellt haben, dass der genaue Wert 5033932 ist. Ich nehme an, dass die Berechnung intern einen Fudge-Faktor beinhaltet.

Sie müssen also erhöhen, innodb_log_file_sizewenn Sie größere BLOB / TEXT-Daten speichern möchten. Glücklicherweise ist das Ändern der Größe der Protokolldatei in 5.6 viel einfacher als in früheren Versionen von InnoDB. Fügen Sie einfach eine Zeile in Ihrer my.cnf mit dem neuen Wert hinzu und starten Sie mysqld neu.

Bill Karwin
quelle
kleine Notiz, Sie müssen neu starten oder anhalten und erneut starten, damit die Änderung beeinflusst wird. Das Neuladen funktioniert nicht
Hieu Vo
1
Diese Größenbeschränkung für Wiederholungen wird auf 10% der gesamten kombinierten innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group) von mysql 5.6.22 gelockert. Und der Longblob kann eine maximale Länge von 4294967295 (2 ^ 32 - 1) Zeichen haben, dh 4 GB. Um diesen Longblob-Wert zu speichern, sollten mindestens 40 GB kombiniert werden. Innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group).
Kasi