«Error at offset X of Y bytes in variable_initialize», MySQL и кодировки

Главные вкладки

Аватар пользователя vkapas vkapas 8 мая 2015 в 13:03

Хотел бы написать об одной из причин появления ошибки вида
Notice: unserialize() [function.unserialize]: Error at offset X of Y bytes in variable_initialize() (line 935 of /includes/bootstrap.inc).
которая у меня возникла при обновлении с Drupal 6 на 7, и о способе её решения.

В моём случае проблема выглядела примерно так:

1. После непродолжительного поиска я нашёл на форуме обсуждение похожей ошибки, где приводилось следующее решение:

  • установка Variable Check;
  • поиск в отчётах модуля (admin/reports/variablecheck) переменных, вызывающих ошибку;
  • удаление переменных.

2. Мне повезло, и у меня, как и у некоторых пользователей этого модуля, сам модуль не удалял переменные, не показывая при этом ни ошибки, ни отчёта об успешном удалении.

Также я обратил внимание на то, что абсолютно все пемеренные в отчёте Variable Check содержали кракозябры в виде символов �:

что навело на мысли о проблемах с кодировкой. Как оказалось позже, за кракозябрами, действительно, скрывались кириллические и спецсимволы (напр., длинные тире).

3. Реальную причину ошибки я нашёл, когда полез своими шаловливыми руками в БД удалять значения «кривых» переменных. Там я видел следующее:

Как можно заметить, таблица drupal_variable хранилась в кодировке cp1251_general_ci, это и оказалось причиной всех бед.

Проблему решил как умел:

  1. Экспортировал значения каждой проблемой переменной с помощью phpMyAdmin в файл вида drupal_variable-value.bin.
  2. С помощью текстового редактора (Gedit) пересохранил файл в UTF-8.
  3. Импортировал обновлённые файлы обратно с помощью того же phpMyAdmin.

После этого хорошим завершением и защитой от проблем с кодировками в будущем также станет конвертация всех не-utf8 таблиц в utf8. Здесь мне снова повезло, т.к. я пользуюсь (внимание, реклама!) самым лучшим Drupal-хостингом, и любезная ТП моего хостера самостоятельно конвертировала все таблицы из cp1251_general_ci в utf8_general_ci по моей просьбе.

Надеюсь, данный пост поможет друпалерам, столкнувшимся с похожей проблемой, и сэкономит им время на её решение.
Буду благодарен за описание более простых решений по конвертации значений/таблиц БД.