必须同时修改my.cnf中[client]、[mysql]、[mysqld]三段配置并重启验证,仅改[mysqld]段character-set-server无效;[mysqld]设utf8mb4及对应校对规则,[client]和[mysql]设default-character-set=utf8mb4,重启后需验证四个character_set变量全为utf8mb4,已有库表须手动ALTER转换,应用连接也需显式指定charset。
只在 [mysqld] 段写 character-set-server = utf8mb4 是无效的。MySQL 启动时会分别读取 [client]、[mysql]、[mysqld] 三段配置,各自控制不同层级:
[mysqld]:决定新库/新表默认字符集和排序规则,必须配 character-set-server = utf8mb4 和 collation-server = utf8mb4_0900_ai_ci(MySQL 8.0+ 推荐,别用 utf8mb4_unicode_ci)[client]:影响所有客户端工具(如 mysqldump、mysqladmin)的默认连接字符集,加 default-character-set = utf8mb4
[mysql]:专用于 mysql 命令行客户端自身,也加 default-character-set = utf8mb4,否则命令行连上后 character_set_client 仍是 utf8
Windows 用户注意路径:C:ProgramDataMySQLMySQL Server X.Xmy.ini;宝塔用户进【软件商店】→ MySQL → 【设置】→ 【配置修改】;Docker 必须挂载自定义 my.cnf 到 /etc/mysql/my.cnf,权限设为 644,否则静默跳过。
改完配置不验证,等于没改。连接 MySQL 后执行:
SHOW VARIABLES LIKE 'character%';
必须全部满足:
character_set_client = utf8mb4character_set_connection = utf8mb4character_set_results = utf8mb4character_set_server = utf8mb4任一值仍是 utf8 或 latin1,说明配置未加载——常见于段落写错(比如误写到 [mysqld_safe] 下)、路径不对、或被其他同名配置覆盖。Linux 下若用 mysql -u root -p 连接后 STATUS; 显示 via socket,可能未读取 [client] 段,可强制走 TCP 测试:mysql -h 127.0.0.1 -u root -p。
character-set-server 只影响新建库表,对已存在对象完全无效。哪怕你改完重启、验证全绿,老库里的表结构仍保持原字符集,DESCRIBE table_name 看不出异常,但插入 emoji 依然失败。转换必须手动,且顺序不能错:
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(注意:用 MODIFY COLUMN 不会重编码已有数据,旧乱码还是乱码)TEXT/VARCHAR 字段长度——utf8mb4 单字符最多占 4 字节,若原字段为 VARCHAR(255),实际最大字节数是 1020,可能触发 Row size too large 错误大表建议低峰期操作,并确认 innodb_file_format = Barracuda 且 innodb_large_prefix = ON,避免索引长度超限。
服务端和表都改了,应用连上去还是存乱码?大概率是客户端没对齐。MySQL 连接有三层字符集:character_set_client、character_set_connection、character_set_results,其中前两者决定 SQL 文本如何解码。常见错误:
mysqli 没调 mysqli_set_charset($conn, 'utf8mb4'),或 PDO DSN 漏了 ;charset=utf8mb4
useUnicode=true&characterEncoding=utf8mb4(注意是 utf8mb4,不是 utf8)mysql -u root -p 进去后,SET NAMES utf8mb4 只对当前会话有效,退出即失效验证方式:登录后执行 SHOW VARIABLES LIKE 'character_set%';,client、connection、results 三项必须都是 utf8mb4。漏掉这一层,前面所有配置都白搭。