Pull to refresh

8123 байта хватит каждому

MySQL *
Сегодня во время перевода одного сайта с таблиц MyISAM на InnoDB, у последних выяснилась одна интересна особенность. Запрос на изменение движка для двух таблиц возвращал странную ошибку «Got error 139 from storage engine». После поиска информации на эту тему, было выяснено, что данная ошибка возникает тогда, когда какая-либо строка таблицы не вмещается в половину страницы памяти, с которыми работает MySQL. Страницы эти равны 16 Кб, а половина, стало быть, 8 Кб.

Само по себе ограничение довольно странное, но на первый взгляд кажется трудно достижимым, ведь как известно, MySQL хранят текстовые данные в хранилище, отдельном от табличных строк. Оказалось, что это верно только на половину. На самом деле InnoDB хранит в отдельном хранилище только «излишки», к коим он не относит первые 768 байтов каждого текстового поля. Т.е. любой текст будет отъедать от длины строки столько байт, сколько он содержит, но не больше 768. Несложно подсчитать, что максимальное число текстовых полей длиной от 768 байт, которое можно безопасно хранить в одной таблице — 10. И действительно, если запустить пример, все пройдет гладко. Но стоит увеличить количество полей хотя бы на одно, и мы получим ту же ошибку, что и в начале.

Больше всего поражает не абсурдность ограничения, и даже не «прожорливость» строковых типов данных, а умалчивание этой проблемы. InnoDB позволяет совершенно спокойно создавать таблицы с сотнями текстовых полей. При этом о том, что вы не сможете ими воспользоваться, вы узнаете только на продакшене при заполнении таблицы реальными данными. Невнятное сообщение об ошибке тоже оставляет мало положительных эмоций.

Бороться с недугом можно двумя способами:

Перекомпиляция с увеличением UNIV_PAGE_SIZE (продолжение).

Подключение InnoDB через плагин, поддерживающий формат файлов barracuda и изменение ROW_FORMAT у таблиц на DYNAMIC. Или просто использование ROW_FORMAT=DYNAMIC, если у вас уже MySQL 5.5.
Tags:
Hubs:
Total votes 82: ↑75 and ↓7 +68
Views 10K
Comments Comments 27