J'utilise un serveur MySQL sur mon Macbook (pour les tests). La version est 5.6.20 de Homebrew. J'ai commencé à rencontrer des erreurs de "taille de ligne trop grande" et j'ai pu la réduire à ce cas de test. Table:
mysql> describe test;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| stuff | longtext | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
Statut de la table:
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 | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
L'erreur que j'obtiens lorsque j'essaie d'insérer une ligne dans la table où la colonne stuff
a plus de 5033932 octets.
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.
J'ai cherché cette erreur, la plupart des réponses impliquent d'avoir trop de colonnes TEXT, et chacune a 768 octets stockés en ligne. Comme vous pouvez le voir, ce n'est pas le cas pour moi. En outre, le nombre 5033932 reste le même quel que soit le nombre de colonnes que j'ai dans le tableau. Dans mon application d'origine, il y avait cinq colonnes et les mises à jour échouaient toujours lorsque la taille de la colonne dépassait 5033932.
J'ai également vu des gens résoudre le problème en changeant de format de ligne, ce que j'essaierai un peu, mais j'aimerais comprendre exactement ce qui cause cette erreur.
Merci d'avance!
Un changement dans les notes de version 5.6.20:
Les écritures de journalisation des grands champs BLOB stockés en externe peuvent remplacer le point de contrôle le plus récent. Le correctif 5.6.20 limite la taille des écritures BLOB de journalisation à 10% de la taille du fichier de journalisation. Le patch 5.7.5 corrige le bogue sans imposer de limitation. Pour MySQL 5.5, le bogue reste une limitation connue.
En raison de la limite d'écriture BLOB de rétablissement du journal introduite pour MySQL 5.6, innodb_log_file_size doit être défini sur une valeur supérieure à 10 fois la plus grande taille de données BLOB trouvée dans les lignes de vos tables, plus la longueur des autres champs de longueur variable (VARCHAR, VARBINARY et champs de type TEXTE). Sinon, cela pourrait entraîner des erreurs "Taille de ligne trop grande".
(c'est moi qui souligne)
La valeur par défaut pour innodb_log_file_size
est 50331648, ce qui signifie que la plus grande valeur BLOB/TEXTE que vous pouvez créer, quel que soit le type de données, est proche de 5033164, et vous avez découvert que la valeur précise est 5033932. Je suppose qu'en interne, le calcul implique un facteur de fudge.
Vous devez donc augmenter innodb_log_file_size
si vous souhaitez stocker des données BLOB/TEXT plus volumineuses. Heureusement, la modification de la taille du fichier journal est beaucoup plus facile dans 5.6 que dans les versions antérieures d'InnoDB. Ajoutez simplement une ligne dans votre my.cnf avec la nouvelle valeur et redémarrez mysqld.