Исправляем ошибку MySQL «Row size too large» в 1с-Битрикс

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Если Вы используете в своих проектах инфоблоки 2.0 и таблицы InnoDB, то есть шанс в один прекрасный момент столкнуться с ошибкой MySQL «SQL Error (1118): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs» (или «Got error 139 from storage engine»). Ниже рассмотрены причины и условия ее возникновения, а также различные методы устранения, с вмешательством в настройки сервера или без него.

Причины

Данная ошибка возникает в таблицах InnoDB при попытке чтения строки с большим количеством заполненных текстовых полей. Сумма длин всех текстовых полей (но не более 768 байтов каждого поля) не должна превышать половины страницы памяти, которая указана в настройках MySQL. В моем случае это было 16кб, отсюда и цифра 8126 байт в названии ошибки.

Условия возникновения в 1с-Битрикс

К ошибке приводит совокупность факторов:
- использование инфоблоков 2.0, т.е. хранение свойств в отдельных таблицах;
- MySQL в качестве сервера базы данных;
- тип InnoDB для таблицы свойств инфоблока;
- большое количество свойств строкового типа. Точная цифра зависит от настроек сервера.

Методы решения

Условно решения можно разделить на 2 группы — с необходимостью правки конфигурации сервера и без нее. Все советы даны применительно к битриксу. Естественно перед экспериментами нужно сделать резервную копию.

Без правки конфигурации:

1. Перевести таблицу в MyISAM. В моем случае это вызвало 2 проблемы — битрикс неправильно конвертировал заполненные значения свойств и при первом добавлении элемента инфоблока пропали половина свойств других элементов. Почему именно так получилось не ясно, но факт остается фактом — риск поломать таблицу есть.

2. Вернуться на инфоблоки 1.0. В этом случае каждое свойство будет храниться в отдельной строке общей таблицы, строка «влезет» в отведенную ей память и ошибка пропадет. Метод не всегда применим, потому что есть некоторые различия в форматах объектов, возвращаемых функцией CIBlockElement::GetList(), и в некоторых случаях придется переписывать код.

С вмешательством в настройки сервера:

1. Увеличить размер страницы памяти. Для этого в файле univ.i установить значения

#define UNIV_PAGE_SIZE (8 * 8192)
#define UNIV_PAGE_SIZE_SHIFT 16

и пересобрать MySQL.

Минусы подхода хорошо описаны в этой статье.

2. Для MySQL версии > 5.5 изменить формат таблиц на DYNAMIC

ALTER TABLE tableName ENGINE = InnoDB ROW_FORMAT = Dynamic;

Для MySQL версии > 5.0 нужно сначала подключить InnoDB через плагин, поддерживающий формат файлов barracuda.

Хостинг TimeWeb точно подвержен этой ошибке. Будьте внимательны и заранее продумывайте архитектуру проекта.

Интересные статьи

Интересные статьи

Тема статьи навеяна результатами наблюдений за методикой создания шаблонов различными разработчиками, чьи проекты попадали мне на поддержку. Порой разобраться в, казалось бы, такой простой сущности ка...
Эта статья посвящена одному из способов сделать в 1с-Битрикс форму в всплывающем окне. Достоинства метода: - можно использовать любые формы 1с-Битрикс, которые выводятся компонентом. Например, добавле...
Одной из «киллер-фич» 12й версии Битрикса была объявлена возможность отдавать статические файлы из CDN, тем самым увеличивая скорость работы сайта. Попробуем оценить практический выигрыш от использова...
Мы публикуем видео с прошедшего мероприятия. Приятного просмотра.
В «1С-Битрикс» считают: современный интернет-магазин должен быть визуально привлекательным, адаптированным для просмотра с мобильных устройств и максимально персонализированным с помощью технологии Бо...