Помилка розміру рядка з 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.

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

Спасибі заздалегідь!

Відповіді:


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_size- 50331648, що означає, що найбільше значення 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).
kasi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.