linux下mysql中文文件名乱码需四者对齐:系统locale设为utf-8、mysql服务端及客户端连接编码设为utf8mb4、表字段显式指定utf8mb4字符集与排序规则,且每步须用show variables和show create table交叉验证。

Linux 下 MySQL 存中文文件名乱码,根本不是单改 character_set_database 就能解决的——系统 locale、客户端连接编码、表字段字符集、甚至文件系统挂载参数,四者必须对齐。
查清当前 MySQL 各层字符集是否真为 utf8mb4
很多人只改了配置文件就以为万事大吉,但 show variables like '%char%' 显示的值可能被 session 覆盖,或未生效。重点看这四个变量:
-
character_set_client:客户端发来的 SQL 字符串按什么编码解析 -
character_set_connection:MySQL 内部转换用的中间编码(应与 client 一致) -
character_set_database:当前库默认字符集(影响新创建表) -
character_set_server:服务端默认字符集(影响新库、新连接默认值)
如果其中任意一个是 latin1 或 utf8(注意:不是 utf8mb4),插入中文文件名(如 "测试_上传.jpg")就可能报 Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...' for column 'filename'。
Linux 系统 locale 必须显式设为 UTF-8
MySQL 客户端(比如 mysql 命令行工具)会继承 shell 的 locale 设置。若 locale 输出中 LANG 是 en_US 或 zh_CN.GB2312,即使 MySQL 服务端是 utf8mb4,客户端也会以错误编码发送字符串。
验证方式:locale | grep -i utf —— 应看到 LANG=zh_CN.UTF-8 或 LANG=en_US.UTF-8
临时修复:export LANG=zh_CN.UTF-8export LC_ALL=zh_CN.UTF-8
永久生效(推荐):
编辑 /etc/locale.conf,写入:LANG="zh_CN.UTF-8"
然后运行 localectl set-locale LANG=zh_CN.UTF-8 并重启终端。
表字段必须用 utf8mb4 + 对应 collation
仅把数据库或表设为 utf8 不够——那是 MySQL 的旧别名,实际只支持最多 3 字节的 Unicode 字符(不含 emoji 和部分生僻汉字)。中文文件名常含扩展区汉字或连字符,必须用 utf8mb4。
检查字段实际编码:SHOW FULL COLUMNS FROM your_table LIKE 'filename'; —— 看 Collation 列是否为 utf8mb4_unicode_ci 或 utf8mb4_general_ci
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
修改字段(不可省略 MODIFY 或 CHANGE):ALTER TABLE your_table MODIFY filename VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:
- 不要用 CONVERT TO CHARACTER SET,它可能静默截断超长字段
- 如果字段有索引且长度超 191,需先删索引再改,否则报错 Specified key was too long
连接时显式指定 charset,绕过环境干扰
应用代码或命令行连接 MySQL 时,不要依赖默认设置。例如:
PHP PDO:$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
Python PyMySQL:conn = pymysql.connect(..., charset='utf8mb4')
命令行客户端:mysql --default-character-set=utf8mb4 -u root -p
这样可确保从连接建立那一刻起,client → connection → server 全链路都是 utf8mb4,不被 shell locale 或 my.cnf 中遗漏项拖累。
最容易被忽略的是:改完配置后没重启 MySQL 服务,或改了服务端却忘了改客户端连接参数;还有人把表字符集改了,但字段定义里仍写着 CHARACTER SET latin1,导致 ALTER 语句根本没生效。每一步都得用 SHOW CREATE TABLE 和 SHOW VARIABLES 交叉验证,不能只信“我改过了”。










