最简单有效的解法是用 mysql_config_editor 替换脚本中的 -p'xxx';它将凭据加密存入 ~/.mylogin.cnf(权限600),通过 --login-path 参数调用,避免密码明文暴露在 ps、history 等中。

直接用 mysql_config_editor 替换脚本里的 -p'xxx',是最简单、最有效、且官方原生支持的解法。其他方案(如环境变量、~/.my.cnf)要么客户端不默认读取,要么权限/路径容易出错,反而增加维护负担。
为什么明文密码在备份命令里等于裸奔
只要命令行出现 -p'xxx' 或 --password=xxx,密码就会出现在:ps aux 输出里、shell history 里、系统审计日志(如 /var/log/audit/),甚至被容器运行时或 APM 工具捕获。MySQL 官方文档明确将这种写法标记为「不安全」。
常见错误现象:
-
mysqldump -u backup -p'secret123' db被 cron 执行后,运维执行ps aux | grep mysqldump就能看到完整密码 - 脚本调试时加了
set -x,所有参数(含密码)全量打印到日志 - 备份失败报错信息里带出
Access denied for user 'backup'@'localhost' (using password: YES),间接确认密码存在且被尝试
怎么用 mysql_config_editor 创建 login-path
它把凭据加密(实为混淆)存进 ~/.mylogin.cnf,权限自动设为 600,只有当前用户可读;后续所有 MySQL 客户端工具都能自动识别 --login-path 参数。
实操建议:
- 运行
mysql_config_editor set --login-path=backup --user=backup_user --host=localhost --password,回车后交互输入密码(不回显、不进 history) -
--login-path名字可自定义,比如prod、staging,方便多环境隔离 - 验证是否生效:
mysqldump --login-path=backup --no-defaults database_name | head -n5,能输出就说明连通 - 查看配置内容(不含密码):
mysql_config_editor print --login-path=backup - 删错重来:
mysql_config_editor remove --login-path=backup
备份脚本里怎么替换?注意这 3 个坑
不是改一个参数就完事——--login-path 行为和传统 -u/-p 不完全等价,容易踩空。
常见错误现象:
- 脚本在 cron 里跑失败,但手动执行正常 → cron 默认没加载用户 shell 环境,
~可能解析成/root;务必用绝对路径调用,或在 crontab 中加HOME=/home/youruser -
mysqldump --login-path=backup db | gzip > /backup/db.sql.gz报错Access denied→ 检查mysql_config_editor print --login-path=backup输出的host是否和权限表匹配(localhost≠127.0.0.1) - 误以为设置一次就全局生效 →
--login-path只对当前命令有效,每个mysqldump、mysqladmin、mysqlbinlog都得显式带上
最容易被忽略的一点:即使 mysql_config_editor 用了,账号本身权限也必须最小化。如果 backup_user 有 DROP 或 FILE 权限,攻击者拿到这个 login-path 后就能执行任意 SQL,比如 mysql --login-path=backup -e "SELECT ... INTO OUTFILE" 写 shell。











