#Как проявляется проблема и где искать причину
При переезде MySQL проблема с utf8mb4 обычно возникает из-за отличающихся кодировок соединения, таблиц или сортировок на старом и новом сервере. Нельзя исправить «кракозябры» простым повторным перекодированием, если байты уже были повреждены.
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Несовпадение соединенийКлиент отправляет строки не в той кодировке | Проблема только при импорте/записи | Установить верный charset на уровне драйвера |
| Коллизия сортировокДамп использует collation, которой нет на целевой версии | Unknown collation при импорте | Выбрать поддерживаемую сортировку после проверки версии |
#Пошаговая диагностика и устранение
- 1. Сохраните исходные данныеДо любых изменений создайте проверенный дамп исходной базы и зафиксируйте версии MySQL обоих серверов. Если данные важны, выполните пробное восстановление в отдельной базе. Не перезаписывайте единственный оригинал.
- 2. Посмотрите параметры соединенияВ mysql-клиенте проблемного окружения выполните запрос; обратите внимание на client, connection и results. Параметры относятся к текущему соединению, а не автоматически ко всем приложениям.
- Запуск в mysql-клиенте под пользователем с доступом на чтениеSQLКомандаЗапуск в mysql-клиенте под пользователем с доступом на чтение.
SHOW VARIABLES LIKE 'character_set_%';
- 3. Уточните настройку схемыВ клиенте проверьте реальную кодировку и сортировку схемы, заменив appdb её именем. Сверьте со значениями до переноса.
- SQL в mysql-клиенте; замените appdb и проверьте доступSQLКомандаSQL в mysql-клиенте; замените appdb и проверьте доступ.
SHOW CREATE DATABASE appdb;
- 4. Проверьте проблемную таблицу и столбецОткройте структуру таблицы и отметьте charset/collation нужного строкового столбца. Например, если таблица хранит utf8mb4, но приложение передаёт байты cp1251, причина может быть в соединении или импортёре.
- Замените appdb.messages на реальную таблицу; чтениеSQLКомандаЗамените appdb.messages на реальную таблицу; чтение.
SHOW FULL COLUMNS FROM appdb.messages;
- 5. Найдите ошибку по контрольным строкамНа исходном и тестовом серверах сравните одну и ту же запись, её читаемое содержимое и HEX значения. Если байты различаются, не пытайтесь «угадать» кодировку по отображению браузера: определите точную ступень повреждения.
- 6. Настройте драйвер подключенияЕсли соединение ошибочно использует другой charset, в поддерживаемом клиенте задайте utf8mb4 при установлении соединения. Команда SET NAMES действует только для текущей сессии и не исправляет уже испорченные данные.
- Только текущая сессия MySQL; в коде предпочтительны настройки самого драйвераSQLКомандаТолько текущая сессия MySQL; в коде предпочтительны настройки самого драйвера.
SET NAMES utf8mb4;
- 7. Отработайте преобразование на тестеЕсли выявлена отсутствующая сортировка, найдите эквивалент, поддерживаемый целевой версией, и испытайте импорт дампа на отдельной базе. Если выявлены неверно перекодированные байты, восстановите корректные записи из оригинала; массовое преобразование применяйте только после сравнительного теста.
- 8. Подтвердите результат на полном путиПосле правки проверьте чтение и запись кириллицы, символов вне BMP и сортировку в приложении. При расхождении вернитесь к копии и проверьте, не меняет ли текст дополнительный слой PHP/HTTP/браузер.
#Как проверить результат
Контрольные записи в обеих кодировках отображаются одинаково на тесте, байты не искажаются, импорт проходит без Unknown collation.
#Если исправление не помогло
Для старых дампов с набором байтов cp1251 сначала установите реальную исходную кодировку по образцу, а не применяйте utf8mb4 ко всем исходным файлам.