Миграция Magento 2 с utf8 на utf8mb4

Один из клиентов использовал эмодзи в своем имени. База данных обрезала имя сразу после эмодзи. В логах при этом не появилось никаких ошибок.

Проблема заключается в MySQL utf8. Это не настоящий UTF-8, а кодировка с ограничением в три байта.

Для эмодзи и многих современных символов требуется четыре байта. Если вы используете старый utf8, MySQL обрезает ваши данные. Если ваш SQL mode не является строгим (strict), это происходит незаметно. Вы теряете данные, даже не подозревая об этом.

Решение — utf8mb4. Она поддерживает четыре байта на символ.

Вы не можете просто запустить команду конвертации для крупного магазина Magento. Скорее всего, вы столкнетесь с ошибкой. Ошибка будет гласить, что ваш ключ слишком длинный.

Это происходит потому, что MySQL рассчитывает размер индекса на основе максимально возможного количества байт. Столбец VARCHAR(255) использует 765 байт в utf8. В utf8mb4 тот же столбец требует 1020 байт. Это превышает старый лимит в 767 байт.

Как это исправить:

  • Используйте MySQL 8.0 или MySQL 5.7 с включенным параметром innodb_large_prefix. Это увеличит ваш лимит до 3072 байт.
  • Если вы используете старый сервер, уменьшите длину индексируемых столбцов VARCHAR до 191 символа. 191 символ, умноженный на 4 байта, составляет 764 байта. Это вписывается в лимит.

Успешная миграция требует трех шагов:

  1. Обновите базу данных и таблицы. Используйте ALTER TABLE CONVERT TO CHARACTER SET utf8mb4. Это перезапишет существующие данные.
  2. Обновите настройки сервера по умолчанию в файле my.cnf. Это гарантирует, что новые таблицы будут использовать правильные параметры.
  3. Обновите кодировку соединения приложения. Если соединение останется в utf8, данные будут повреждены еще до того, как попадут в базу данных.

Остерегайтесь следующих рисков:

  • Блокировка таблиц. CONVERT TO перезаписывает всю таблицу. Большие таблицы будут заблокированы. Используйте такие инструменты, как pt-online-schema-change, чтобы ваш магазин оставался доступным.
  • Несоответствие кодировок (collation). Все объединяемые (joined) таблицы должны использовать одну и ту же кодировку. Используйте utf8mb4_unicode_ci во всей вашей схеме.

Если вы все еще используете utf8, ваш магазин не является Unicode-безопасным. Вы просто ждете, когда какой-нибудь «неправильный» символ испортит ваши данные.

Источник: https://dev.to/iamrobindhiman/migrating-a-magento-2-store-from-utf8-to-utf8mb4-without-losing-data-khn