必须同步配置character-set-server、collation-server和init_connect三项,并补全[client]与[mysql]段default-character-set=utf8mb4,否则连接、客户端、会话、字段无法全链路生效,root用户还需手动执行SET NAMES utf8mb4。

只改 character-set-server 会漏掉三个关键环节
MySQL 8.0 启动后 @@character_set_server 确实默认是 utf8mb4,但仅靠它无法保证连接、客户端、会话、字段全链路生效。常见现象包括:mysql 命令行输入中文显示问号、Python pymysql 报错 2059、Navicat 插入 emoji 失败。根本原因是服务端字符集 ≠ 连接时协商的字符集 ≠ 客户端工具默认行为。
必须同步配置以下三项:
-
character-set-server=utf8mb4:影响新建库/表的默认字符集 -
collation-server=utf8mb4_0900_ai_ci:必须显式指定,否则可能 fallback 到utf8mb4_general_ci(已弃用) -
init_connect='SET NAMES utf8mb4':让每个普通用户连接成功后自动执行,设好会话级三要素(character_set_client/connection/results)
my.cnf 中 [client] 和 [mysql] 段不能省
即使 [mysqld] 段全配对了,mysql 命令行工具仍可能乱码——因为它根本不读 [mysqld],而是优先读 [client] 和 [mysql] 段。不配这两段,你用 mysql -u root -p 登录后执行 INSERT INTO t VALUES ('??'); 就会报错或存成 ??。
需在 my.cnf 中补上:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4
注意:[mysql] 是专为 mysql 客户端命令设的,[client] 是通用段,被所有 MySQL 客户端程序(如 mysqldump)读取。
为什么必须用 utf8mb4_0900_ai_ci 而不是 utf8mb4_unicode_ci
utf8mb4_0900_ai_ci 是 MySQL 8.0 默认且唯一推荐的排序规则。它基于 Unicode 9.0,对 emoji、德语 ß、越南语重音等处理更准;而 utf8mb4_unicode_ci 基于旧版 Unicode,'ß' = 'ss' 在 _ai_ci 下返回 1(正确),在 unicode_ci 下返回 0(错误)。混用两者还会触发 ERROR 1267: Illegal mix of collations。
迁移老表时尤其注意:
-
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4不带COLLATE→ 自动变成utf8mb4_0900_ai_ci,可能意外改变大小写敏感逻辑 - 正确写法是:
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci - 已有字段若明确依赖
utf8mb4_unicode_ci行为,必须显式保留,不能靠默认
init_connect 对 root 或 SUPER 权限用户不生效
init_connect 只对普通用户连接有效,root 或拥有 SUPER 权限的用户登录时不会执行该语句。这意味着你用 mysql -u root 登录后,SHOW VARIABLES LIKE 'character\_set%'; 仍可能看到 latin1 或 utf8 ——这不是配置失效,是设计如此。
解决办法只有两个:
- 日常运维尽量用普通账号(如
admin),避免长期用 root 直连 - 若必须用 root,每次登录后手动执行:
SET NAMES utf8mb4;
这个限制常被忽略,导致反复排查“明明配了 init_connect 为什么 root 还乱码”。


















