[БУСКОНВЕРТ] 🐱‍👤 Конвертация базы из utf8 в utf8mb4

Озадачился я на днях с BB-редактором для модуля комментариев и оказалось, что Windows 10 Emoji не работают в utf8 кодировке, для 1C Битрикс Emoji нужна utf8mb4 кодировка.

Оказывается уже и кодировка utf8 считается морально устаревшей, вместо нее лучше использовать кодировку utf8mb4, т.к. она поддерживает гораздо большее количество символов выше 0xFFFD, в том числе Bitrix Emoji, полностью совместима с utf8 и поддерживается сервером MySQL с версии 5.5.3.

Итак, если кодировка (charset) будет utf8mb4, то сравнение (collation) будет utf8mb4_unicode_ci

Кодировка MySQL-сервера

Можно в самом конфиге MySQL (my.cnf) задать кодировку сервера и соединения по умолчанию.
Но если вы в этом ничего не понимаете или у вас шаред, то пропустите этот шаг, достаточно будет настроить это в конфигах Битрикса для конкретного сайта, а не всего сервера.

[mysqld]character-set-server=utf8collation-server=utf8_unicode_ciinit-connect="SET NAMES utf8 COLLATE utf8_unicode_ci"

Кодировка новой базы

Если создается новая база под новый проект, например в программе HeidiSQL, то достаточно задать сравнение, все новые таблицы будут использовать сравнение базы, тут все просто.


Кодировка существующей базы

Это самое сложное, сделать конвертацию действующей базы на рабочем проекте, просто поменять сравнение у базы и таблиц будет недостаточно, еще нужно задать сравнение и кодировку всем полям таблицы типа: char, varchar, tinytext, text, mediumtext, longtext, enum, set, json

Для автоматизации конвертации всей базы я написал свой скрипт busconvert.php, его нужно залить на сайт на Битриксе, в любое место, главное открыть его в браузере и нажать кнопку Начать конвертацию.

BUSCONVERT v1.0.0

Сначала скрипт выводит текущие значения кодировки и сравнения до конвертации.
После нажатия на кнопку Начать конвертацию скрипт начнет конвертировать всю текущую базу сайта.

Выделено желтым - кодировка, в которую скрипт будет конвертировать.
Выделено красным- текущие значения.

По окончании работы выводит результаты После конвертации и Лог конвертации, а также количество затронутых таблиц  и новую кодировку базы, если все прошло успешно.

В таблице лога выводится новая кодировка и все SQL-запросы, которые совершал скрипт над данными полей каждой таблицы.

После успешной конвертации остается поменять настройки соединения с базой в 2-х файлах.
Здесь в запросах заменяем utf8 на utf8mb4

//bitrix/php_interface/after_connect.php$DB->Query("SET NAMES 'utf8mb4'");$DB->Query('SET collation_connection = "utf8mb4_unicode_ci"');//bitrix/php_interface/after_connect_d7.php$connection = \Bitrix\Main\Application::getConnection();$connection->queryExecute("SET NAMES 'utf8mb4'");$connection->queryExecute('SET collation_connection = "utf8mb4_unicode_ci"');

А также в файле /bitrix/.settings.php

'utf_mode' =>  array(     'value'    => true,     'readonly' => true,  ),

Еще желательно сбросить весь кэш сайта, либо в админке, либо удалив вот эти папки с диска.

/bitrix/cache/bitrix/managed_cache/bitrix/stack_cache/bitrix/html_pages/example.com

Все, это должно помочь, других настроек нет.

Чтобы проверить новую кодировку откройте статью, новость или товар, и в форме редактирования, например, в названии вставьте Windows 10 Emoji комбинация Windows + . в английской раскладке.

Вот такая красота Emoji 🤞😜🤞 будет везде, и в заголовке страницы, и в хлебных крошках, и в заголовке окна браузера, и в результатах поиска Google и Yandex ваши материалы станут более заметны!

Заметки

1) Скрипт будет работать, даже если закрыть окно браузера, пока все не выполнит.

2) Скрипт тестировался только на кодировке utf8, для кириллицы cp1251 пока не подходит, позже постараюсь и этот момент доработать.

3) Если все же хочется попробовать другую кодировку, то изменяйте значение в этих переменных в самом начале скрипта.

$charset = 'utf8mb4';$collate = 'utf8mb4_unicode_ci';

4) Я базу тестового сайта конвертировал раз 50 и никаких проблем, если что, можно запускать скрипт несколько раз.

5) При конвертации тип и другие параметры поля не изменяются, тщательно все проверил, некоторые запросы почему-то изменяли тип поля text на mediumtext

А проверить это можно инструментом от 1С Битрикс Проверка системы.

Настройки - Инструменты - Проверка системы

Кодировка соединения - будет ругаться, пока Битрикс про это дело не в курсе.
Структура базы данных - Если успешно, значит конвертация прошла успешно, ни одно поле не изменилось в процессе конвертации, важно проверить этот момент еще до конвертации, чтобы потом не гадать, когда это случилось.
Если перед конвертацией скрипт найдет отличающиеся от базы поля, то надо все исправить, кроме случаев, когда вы сами изменяли  поля в таблицах и точно знаете, что делаете.

В этом случае следите за тем, что бы кто-нибудь из ваших разрабов или даже клиент не вернул тут все обратно, скрипт Битрикса может вернуть кодировки обратно в utf8.

6) На двух тестовых сайтах, которые у меня на OSPanel, никаких проблем с конвертацией не было, а вот на текущем пришлось повозиться с такой вот проблемой.

2017-12-05 03:20:12 - Host: tuning-soft.ru - UNCAUGHT_EXCEPTION - [Bitrix\Main\DB\SqlQueryException] Mysql query error: (1071) Specified key was too long; max key length is 767 bytes (400)ALTER TABLE `b_user_option` MODIFY `NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT  NULL ;

Ровно в 20 таблицах пришлось менять тип поля с varchar(255) на varchar(191)

Получется, что для хранения строки utf8 нужно 3 байта на символ, а utf8mb4 нужно 4 байта.
Предел для utf8 составляет 767/3 = ~255 символов, для utf8mb4 это 767/4 = ~191 символ.

  • utf8 VARCHAR(255)
  • utf8mb4 VARCHAR(191)

Но почему-то это не для всех полей varchar(255) требовал, только для некоторых, не знаю почему.

Менял я длину значения поля в базе с помощью своего модуля TSAdminer, вы можете это сделать в любом инструменте для работы с БД.

Ошибки возможно и у вас будут, их просто надо исправить все, пока конвертация не закончится.

Файлы к статье

Имя *
Логин (мин. 3 символа)
E-mail *
*— обязательные для заполнения поля
Логин или e-mail
TUNING-SOFT.RU Разработка умных веб-сервисов