一、问题起源:为什么 mysqldump 导出乱码,而 mysql 命令正常?
场景复现:
ini
# ~/.my.cnf
[mysql]
default-character-set = utf8mb4
结果:
mysql -u root -p连接后中文显示正常 ✅mysqldump -u root -p db > backup.sql导出的 SQL 文件却是latin1编码 ❌
根本原因:把配置写错了位置!
需要理解 [client] 与 [mysql] 区别的关键
二、核心区别:作用范围不同
| 配置段 | 作用对象 | 影响范围 |
|---|---|---|
[client] |
所有 MySQL 客户端工具 | 包括 mysql、mysqldump、mysqladmin、mysqlbinlog 等所有基于 libmysqlclient 的程序 |
[mysql] |
仅 mysql 命令行客户端 |
只影响终端执行 mysql -u root -p 时的行为 |
具体解释
[client] 段
ini
[client]
default-character-set = utf8mb4
- 作用:所有通过 MySQL C API(即 libmysqlclient)连接的程序都会继承此配置。
- 影响的工具 :
mysql(命令行客户端)mysqldump(备份工具)mysqladmin(管理工具)mysqlbinlog(日志解析工具)mysqlcheck/mysqlimport/mysqlshow- 第三方 CLI 工具(如 Percona 的
mydumper) - 部分支持读取 my.cnf 的脚本语言库 (如 Python 的 PyMySQL 若启用
read_default_file)
⚠️ 注意:主流应用层驱动(如 Java JDBC、Go sql/driver、Node.js mysql2)默认不读取 my.cnf,需在连接字符串中显式指定字符集。
[mysql] 段
ini
[mysql]
default-character-set = utf8mb4
- 作用 :仅针对
mysql命令行客户端。 - 不影响 :
mysqldump、mysqladmin等其他工具。
三、配置优先级
当 [client] 和 [mysql] 同时设置相同参数时,生效顺序为:
[client] 全局设置 → [mysql] 专属设置(后者覆盖前者关于MySQL命令行的配置)
##示例场景
情况1:仅配置 [client]
ini
[client]
default-character-set = utf8mb4
结果 :所有客户端工具都使用 utf8mb4
情况2:同时配置 [client] 和 [mysql]
ini
[client]
default-character-set = latin1 # 所有客户端的默认值
[mysql]
default-character-set = utf8mb4 # 覆盖 mysql 客户端的设置
✅ 结果:
mysql命令 → 使用utf8mb4mysqldump/mysqladmin等 → 使用latin1
这就是开头"mysqldump 乱码"问题的根本原因!
四、最佳实践建议
1. 统一字符集:优先配置在 [client]
ini
[client]
default-character-set = utf8mb4
理由:确保所有工具行为一致,避免备份/恢复/管理操作出现编码不一致。
2. 特殊需求:再用 [mysql] 定制命令行体验
ini
[mysql]
prompt = "\\u@\\h:\\\\d \\r:\\m:\\s> " # 自定义提示符
--no-auto-rehash # 不启用自动补全
pager = less -SFX # 大结果集分页
skip-auto-rehash # 在大库中禁用补全以加速连接
📌 注意 :
prompt中的反斜杠需双写(\\u),否则会被 shell 或 MySQL 解析错误。
五、验证配置是否生效
连接数据库后执行:
sql
SHOW VARIABLES LIKE 'character_set_client';
观察返回值是否为你期望的字符集(如 utf8mb4)。
也可以在命令行直接查看客户端默认参数:
bash
$ mysql --print-defaults
mysql would have been started with the following arguments:
--default-character-set=utf8mb4 --host=localhost ...
六、配置加载机制深度解析
6.1 配置文件加载顺序(Linux/Unix)
MySQL 客户端按以下顺序读取配置文件,后加载的会覆盖先加载的同名参数:
/etc/my.cnf/etc/mysql/my.cnf$MYSQL_HOME/my.cnf~/.my.cnf~/.mylogin.cnf(仅用于加密凭证,由mysql_config_editor生成)
调试技巧 :运行
mysql --help,查看底部 "Default options are read from the following files..." 列出的实际路径。
6.2 MySQL命令行优先级层级(从高到低)
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1 | 命令行参数 | 如 mysql --default-character-set=gbk |
| 2 | [mysql] 段 |
仅对 mysql 命令有效 |
| 3 | [client] 段 |
对所有 lib mysql client 工具有效 |
| 4 | 编译默认值 | 通常为 latin1 |
📊 示例:
bashmysql --default-character-set=gbk -e "SHOW VARIABLES LIKE 'char%';"即使
~/.my.cnf中设为utf8mb4,最终仍生效gbk。
七、编程语言驱动是否受 [client] 影响?
| 客户端类型 | 是否读取 my.cnf |
是否受 [client] 影响 |
|---|---|---|
mysql, mysqldump 等官方 CLI |
✅ | ✅ |
Python PyMySQL(启用 read_default_file) |
✅ | ✅ |
| Python mysqlclient (MySQLdb) | ✅ | ✅ |
Go go-sql-driver/mysql |
❌ | ❌ |
| Java Connector/J | ❌ | ❌ |
Node.js mysql2 |
❌ | ❌ |
| PHP PDO / mysqli | ❌(除非调用 mysqli_options(MYSQLI_READ_DEFAULT_FILE)) |
⚠️ 有条件支持 |
🔒 结论 :不要依赖
[client]控制应用层字符集!应在连接字符串中显式指定,例如:
- JDBC:
?useUnicode=true&characterEncoding=UTF-8- Go:
?charset=utf8mb4&parseTime=True- Python:
charset='utf8mb4'
八、配置生效逻辑图
+---------------------+
| 命令行参数 | ← 最高优先级
+----------+----------+
|
+----------v----------+
| [mysql] 段 | ← 仅 mysql 命令
+----------+----------+
|
+----------v----------+
| [client] 段 | ← 所有客户端工具
+----------+----------+
|
+----------v----------+
| 编译默认值 (latin1)| ← 最低优先级
+---------------------+
工具继承关系:
[client] → { mysql, mysqldump, mysqladmin, mysqlbinlog, ... }
↑
[mysql](仅覆盖 mysql)
九、总结
| 场景 | 推荐配置位置 |
|---|---|
| 需要全局生效(如字符集、socket、host) | → 配置在 [client] |
只需定制 mysql 命令行(如 prompt、pager) |
→ 配置在 [mysql] |
| 同时存在时 | → [mysql] 的配置优先级更高(仅对 mysql 命令) |
| 应用程序连接 | → 不要依赖 my.cnf,请在连接串中显式指定 |
终极建议 :
生产环境统一在
[client]中设置default-character-set = utf8mb4,再根据个人习惯在
[mysql]中定制交互体验。