应使用 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
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 任务清理旧文件。
- 动态生成带时间戳的
dest:例如/backup/mysql/{{ inventory_hostname }}_{{ ansible_date_time.iso8601_basic_short }}.sql - 任务前必须用
file模块创建目录,并设好权限(owner: mysql,group: mysql,mode: '0755') - 启用
become: yes,确保有权限写入目标路径 - 任务后加
stat模块检查文件大小是否 > 1MB,防空文件;再用shell模块调用find /backup/mysql -name "*.sql" -mtime +7 -delete清理过期备份
真正落地的备份不是“跑通就行”,而是每台机器的 dest 路径唯一、时间戳格式统一、压缩与校验嵌入脚本、清理策略不依赖人工干预——这些细节一旦松动,批量备份就从自动化退化成定时故障发生器。











