Ошибка размера строки с MySQL

11

Я использую сервер MySQL на своем Macbook (для тестирования). Версия 5.6.20 от Homebrew. Я начал сталкиваться с ошибками «слишком большой размер строки», и мне удалось свести их к этому тесту. Таблица:

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

Статус таблицы:

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

Ошибка, которую я получаю, когда пытаюсь вставить строку в таблицу, где stuffстолбец содержит более 5033932 байта.

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.

Я искал эту ошибку, в большинстве ответов содержится слишком много столбцов TEXT, и в каждом из них по 768 байт хранится в строке. Как видите, это не так для меня. Кроме того, число 5033932 остается неизменным независимо от количества столбцов в таблице. В моем исходном приложении было пять столбцов, и обновления все равно не выполнялись, когда размер столбца превысил 5033932.

Я также видел, как люди решали проблему, переключая форматы строк, что я попробую чуть позже, но я хотел бы точно понять, что является причиной этой ошибки.

Заранее спасибо!

geoffliu
источник

Ответы:

12

Изменение в примечаниях к выпуску 5.6.20:

Записи журнала повторов для больших, сохраненных извне BLOB-полей могут перезаписать самую последнюю контрольную точку. Патч 5.6.20 ограничивает размер записи журнала повторов BLOB до 10% от размера файла журнала повторов. Патч 5.7.5 устраняет ошибку без наложения ограничений. Для MySQL 5.5 ошибка остается известным ограничением.

В результате ограничения записи BLOB журнала повторов, введенного для MySQL 5.6, для innodb_log_file_size должно быть установлено значение, превышающее в 10 раз максимальный размер данных BLOB, найденный в строках ваших таблиц, плюс длина других полей переменной длины (VARCHAR, VARBINARY и поля типа TEXT). Невыполнение этого требования может привести к ошибкам «слишком большой размер строки».

(акцент мой)

По умолчанию используется значение innodb_log_file_size50331648, что означает, что наибольшее значение BLOB / TEXT, которое вы можете создать независимо от типа данных, близко к 5033164, и вы обнаружили, что точное значение равно 5033932. Я полагаю, что внутренне вычисления включают в себя некоторый коэффициент выдумки.

Поэтому вам нужно увеличить, innodb_log_file_sizeесли вы хотите хранить большие данные BLOB / TEXT. К счастью, изменение размера файла журнала в 5.6 намного проще, чем в более ранних версиях InnoDB. Просто добавьте строку в ваш my.cnf с новым значением и перезапустите mysqld.

Билл Карвин
источник
Небольшое уведомление, вы должны перезапустить или остановить и начать заново, чтобы изменения вступили в силу, перезагрузка не работает
Hieu Vo
1
Этот предел размера повторения уменьшен до 10% от общего объединенных innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group) из mysql 5.6.22. И максимальный размер longblob может составлять 4294967295 (2 ^ 32 - 1) символов, т.е. около 4 ГБ. Для хранения этого значения longblob у нас должно быть не менее 40 ГБ, объединенных innodb_log_file_size (innodb_log_file_size * innodb_log_files_in_group).
Каси