应使用 mysql_db 模块而非 shell 调用 mysqldump,因其自动处理连接参数、权限校验、socket 认证、密码策略及幂等性;需显式指定 login_user、login_password、login_host(含 socket 路径)、绝对 dest 路径并配合 backup: yes 与时间戳,且任务前创建目录、启用 become: yes 并校验执行结果后再清理旧备份。
直接用 mysql_db 模块做备份最稳,别手写 mysqldump 命令——模块自动处理连接参数、权限校验和错误退出码,手动命令漏个 --single-transaction 或没设 login_password 就静默失败。
必须用 mysql_db 模块而非 shell 调用 mysqldump
Ansible 的 mysql_db 模块专为数据库操作设计,能正确识别 MySQL 5.7+ 的 socket 认证逻辑和密码策略;而 shell 模块调用 mysqldump 时容易因环境变量缺失(如 PATH 不含 /usr/bin)、未传 --defaults-file 或忽略 login_unix_socket 导致连接失败。
- 模块自动适配
login_unix_socket:首次部署后 root 默认只能走 socket 连接,mysql_db会读取my.cnf或显式参数自动匹配路径(如/var/run/mysqld/mysqld.sock) - 不依赖客户端环境:只要目标机装了
python3-mysql或PyMySQL,模块就能工作;shell方式则要求mysqldump二进制存在且可执行 - 幂等性可控:
state: dump时模块只在name(库名)或dest(输出路径)变更时才重跑,避免重复备份覆盖
mysql_db 备份任务必须显式声明 login_password 和 login_user
MySQL 5.7+ 默认禁用空密码 root 登录,且 Ansible 控制节点无法复用本地 ~/.my.cnf。若只写 login_user: root 却漏掉 login_password,任务会卡住或报错 Access denied for user 'root'@'localhost',而不是提示缺密码。
- 密码不能硬编码在 Playbook 中:用
ansible-vault加密变量,或从外部 vault 服务注入 - 必须指定
login_host:即使连本地,也要写login_host: 127.0.0.1或login_host: localhost,否则模块可能误走 socket 而非 TCP,与预期不符 - 若用 socket 连接,加
login_unix_socket: /var/run/mysqld/mysqld.sock,且确保该路径在目标机真实存在(RHEL/CentOS 和 Ubuntu 路径一致,但自定义安装可能不同)
备份文件路径要带时间戳,且必须用 backup: yes 配合 dest
mysql_db 的 dest 参数只接受绝对路径,且不会自动创建父目录;若路径不存在或权限不足,任务直接失败,不会报“目录不存在”而是报“permission denied”。更关键的是,不加 backup: yes 就无法实现增量归档——模块本身不负责轮转,但启用后可配合后续 find 任务清理旧文件。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
- 动态生成带时间戳的
dest:用"{{ ansible_date_time.iso8601_basic_short }}_backup.sql"或"{{ lookup('pipe', 'date +\%Y\%m\%d_\%H\%M') }}_backup.sql" - 确保
dest所在目录已存在:在mysql_db任务前加file模块创建目录,如path: /data/mysql/backup state: directory mode: '0750' - 权限要匹配 MySQL 用户:目录属主建议设为
mysql,否则 mysqldump 可能因 SELinux 或 umask 限制写入失败
清理旧备份不能只靠 find,得先确认备份成功再删
很多 Playbook 在 mysql_db 后直接跟 command: find /data/mysql/backup -name '*.sql' -mtime +7 -delete,但若备份任务因网络抖动或磁盘满失败,find 仍会执行并删掉所有 7 天前的文件,导致无可用备份。
- 给
mysql_db加ignore_errors: no(默认值,但显式写出来更安全),确保失败中断流程 - 用
register捕获mysql_db输出,检查changed是否为true或failed为false再触发清理 -
find命令加-maxdepth 1防止误删子目录,加-print0 | xargs -0 rm处理含空格的文件名
最易被忽略的是:备份任务里没设 become: yes,导致以普通用户身份运行 mysql_db,而目标机上 MySQL 客户端工具(如 mysql)可能被系统策略限制执行——不是权限问题,是 SELinux 或 AppArmor 拦截,错误日志里只显示 command not found,实际是被策略拒绝。