迁移后出现中文乱码,通常是因为 MariaDB 服务端字符集配置与源 MySQL 不一致,或导入导出时未指定正确字符集。最推荐的处理方向是统一服务端、客户端及连接层为 `utf8mb4`,并在修改配置前备份数据,避免直接修改字符集导致存量数据损坏。
先说结论:解决乱码需同时修正配置文件、连接字符串及存量数据编码,仅改配置不转换数据无法修复已乱码内容。
- 适合:MySQL 迁移至 MariaDB 后出现中文显示问号或乱码的场景
- 先准备:全量备份数据库,确认源库原始字符集编码
- 验收:查询中文数据正常显示,且字符集变量均为 utf8mb4
命令速用版
# 查看当前字符集配置
SHOW VARIABLES LIKE 'character_set%';
# 临时修改会话字符集(不影响存量数据)
SET NAMES utf8mb4;
# 修改数据库默认字符集(新表生效)
ALTER DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;为什么会这样
核心原因是字符集编码和解码环节不匹配。MariaDB 默认配置可能与原 MySQL 不同,若服务端默认是 `latin1` 而客户端发送 `utf8` 数据,存储时字节会被错误解释。迁移过程中 `mysqldump` 若未指定 `--default-character-set`,导出的 SQL 文件可能丢失编码声明,导入新库时按新库默认编码解析,导致中文变成乱码字节。
分步处理
第一步:备份数据
在执行任何字符集修改前,必须使用逻辑备份保留原始数据,防止转换失败导致数据不可逆损坏。mysqldump -u root -p `--all-databases` `--single-transaction` > backup_before_fix.sql
第二步:检查当前配置
登录 MariaDB 执行 SHOW VARIABLES LIKE 'character_set%';。重点关注 character_set_server 和 character_set_database。若显示 latin1 或 utf8(MySQL 中的 utf8 仅支持 3 字节),需调整为 utf8mb4。
第三步:修改配置文件
编辑 MariaDB 配置文件(Linux 通常为 /etc/my.cnf 或 /etc/mysql/mariadb.conf.d/50-server.cnf)。在 [mysqld] 和 [client] 段落下添加或修改以下配置:[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[client]
default-character-set = utf8mb4
修改后需重启 MariaDB 服务生效。
第四步:转换存量数据
若数据在迁移前已乱码,仅改配置无效。需确认原始数据实际编码。若原数据是 utf8 但被存为 latin1 字节,需通过 ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 转换。若数据已损坏,需从备份重新导入,并在导入时指定 `--default-character-set`=utf8mb4。
怎么验证是否生效
执行 SHOW VARIABLES LIKE 'character_set%'; 确认 server、database、connection 均为 utf8mb4。创建一张新表并插入包含生僻字或 emoji 的中文测试数据,执行 SELECT 查询,确认终端或客户端工具显示正常且无问号。检查应用日志,确认无字符集相关警告。
常见坑
1. utf8 不是真正的 UTF-8
MySQL 和 MariaDB 中的 utf8 别名实际是 utf8mb3,最多支持 3 字节,无法存储 emoji 和部分生僻汉字。配置时必须显式指定 utf8mb4。
2. 连接字符串未更新
服务端配置修改后,若应用程序数据库连接字符串(JDBC URL 或 DSN)中未指定 characterEncoding=utf8 或 charset=utf8mb4,客户端仍可能使用默认编码连接,导致乱码。
3. 终端工具编码不一致
数据库服务端已修正,但命令行终端或数据库管理工具(如 Navicat、DBeaver)本身的编码设置若不是 UTF-8,查询结果仍会显示乱码。
常见问题
修改配置后需要重启数据库吗?
需要。修改 my.cnf 中的 character-set-server 属于全局配置,必须重启 MariaDB 服务才能生效,临时修改会话变量不影响新连接。
为什么改了配置历史数据还是乱码?
配置文件只影响新写入的数据。历史数据已按错误编码存储在磁盘上,必须使用 ALTER TABLE ... CONVERT TO CHARACTER SET 转换编码或重新导入正确编码的备份。
MariaDB 和 MySQL 的字符集配置一样吗?
基本一致。MariaDB 兼容 MySQL 协议和大部分配置项,字符集变量名称和配置方法相同,但默认值可能因版本和安装包不同而有差异。
参考来源
- MariaDB Knowledge Base - Character Sets and Collations: https://mariadb.com/kb/en/character-sets-and-collations/
- MySQL Documentation - Character Set Configuration: https://dev.mysql.com/doc/refman/8.0/en/charset-server.html