必须同时配置[client]、[mysql]、[mysqld]三段并重启验证,仅改[mysqld]无效;已有库表不会自动升级,须手动ALTER;连接与应用层也需显式指定charset=utf8mb4。

只改 my.cnf 里的 [mysqld] 段是无效的,必须同时配置三处并重启验证;已有库表不会自动升级,必须手动 ALTER。
my.cnf 必须同时改 [client]、[mysql]、[mysqld] 三段
MySQL 启动时按段分别读取配置,每段控制不同环节:[mysqld] 控制服务端默认值,[client] 影响所有客户端工具(如 mysqldump),[mysql] 专用于 mysql 命令行自身。漏掉任意一段,都可能导致连接层或新建对象仍用 utf8 或 latin1。
-
[mysqld]段加:character-set-server = utf8mb4和collation-server = utf8mb4_0900_ai_ci(MySQL 8.0+ 推荐,别用utf8mb4_unicode_ci) -
[client]段加:default-character-set = utf8mb4 -
[mysql]段加:default-character-set = utf8mb4 - Windows 用户注意路径:
C:\ProgramData\MySQL\MySQL Server X.X\my.ini;Docker 用户必须挂载自定义my.cnf到/etc/mysql/my.cnf,且权限设为644,否则静默跳过
重启后必须执行 SHOW VARIABLES LIKE 'character%' 验证全部四个变量
改完不验证,等于没改。连接 MySQL 后运行该命令,必须全部满足:
character_set_client = utf8mb4character_set_connection = utf8mb4character_set_results = utf8mb4character_set_server = utf8mb4
任一值不是 utf8mb4,说明配置未加载——常见于段落写错(比如误写进 [mysqld_safe])、路径不对、或被其他同名配置覆盖。Linux 下若用 mysql -u root -p 登录后 STATUS; 显示 via socket,可能未读取 [client] 段,可强制走 TCP 测试:mysql -h 127.0.0.1 -u root -p。
已有数据库和表必须手动 ALTER DATABASE 和 ALTER TABLE
character-set-server 只影响新创建的库和表,对已存在的完全无感。即使你重启后新建库,老库里的表依然保持原字符集,DESCRIBE table_name 看不出异常,但插入 emoji 会报 Incorrect string value: '\xF0\x9F\x98\x80'。
- 改当前数据库:
ALTER DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; - 改某张表:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; - 如果只改表结构不转数据,用:
ALTER TABLE tbl_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(不推荐,易遗漏字段)
应用连接也得显式指定 charset=utf8mb4
服务端和库表都配好了,客户端不指定字符集,照样乱码。不同语言驱动要求不同:
- PHP PDO:连接 DSN 加
;charset=utf8mb4,例如mysql:host=localhost;dbname=test;charset=utf8mb4 - Python PyMySQL:构造连接时传
charset='utf8mb4' - Java JDBC:URL 加
?characterEncoding=utf8mb4(注意不是utf-8) - Node.js mysql2:配置项设
charset: 'utf8mb4'
最容易被忽略的是:MySQL 8.0 默认已用 utf8mb4,但很多旧项目沿用历史连接参数,仍带 utf8,这会导致握手失败或降级回 utf8mb3 —— 而 utf8 在新版 MySQL 中已是废弃别名。


















