如何通过Ansible自动化部署MySQL备份任务?

2026-07-09数据库152973

应使用 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-mysqlPyMySQL,模块就能工作;shell 方式则要求 mysqldump 二进制存在且可执行
  • 幂等性可控:state: dump 时模块只在 name(库名)或 dest(输出路径)变更时才重跑,避免重复备份覆盖

mysql_db 备份任务必须显式声明 login_passwordlogin_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.1login_host: localhost,否则模块可能误走 socket 而非 TCP,与预期不符
  • 若用 socket 连接,加 login_unix_socket: /var/run/mysqld/mysqld.sock,且确保该路径在目标机真实存在(RHEL/CentOS 和 Ubuntu 路径一致,但自定义安装可能不同)

备份文件路径要带时间戳,且必须用 backup: yes 配合 dest

mysql_dbdest 参数只接受绝对路径,且不会自动创建父目录;若路径不存在或权限不足,任务直接失败,不会报“目录不存在”而是报“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_dbignore_errors: no(默认值,但显式写出来更安全),确保失败中断流程
  • register 捕获 mysql_db 输出,检查 changed 是否为 truefailedfalse 再触发清理
  • find 命令加 -maxdepth 1 防止误删子目录,加 -print0 | xargs -0 rm 处理含空格的文件名

最易被忽略的是:备份任务里没设 become: yes,导致以普通用户身份运行 mysql_db,而目标机上 MySQL 客户端工具(如 mysql)可能被系统策略限制执行——不是权限问题,是 SELinux 或 AppArmor 拦截,错误日志里只显示 command not found,实际是被策略拒绝。

本文地址:https://www.ufcn.cn/article/2431286.html

如非特殊说明,本站内容均来自于网友自主分享,概不代表本站观点,如有任何问题我们都将在收到反馈后的第一时间进行处理!