ansible自动化部署数据库集群需按角色分组(mysql_masters/mysql_slaves)、动态生成server-id、jinja2模板差异化配置my.cnf、严控初始化权限与路径、幂等化建立主从关系。

利用 Ansible 自动化安装数据库集群,核心不是“装上就行”,而是让每台节点按角色精准就位、配置不偏不倚、初始化稳如磐石。手动部署常因 server-id 重复、read_only 漏设、my.cnf 权限错误或复制账号未创建,导致 Seconds_Behind_Master: NULL 或 ERROR 2003 连不上——这些问题在自动化中必须前置拦截。
严格按角色分组定义 inventory
Ansible 不识别逻辑主从,只认 inventory 中的组名。不能用单个 [dbservers] 统管所有节点再靠 when 判断,否则扩容改主机名就得同步改几十处条件语句。
- 硬性拆分为 [mysql_masters](仅 1 台,写入 + 生成 binlog)、[mysql_slaves](多台,只读 + 拉取 relay log),MGR 场景可加 [mysql_arbiters]
- server-id 必须全局唯一:master 固定为 100,slave 用 201、202 等递增数值,避免硬编码进 vars,应通过 group_names 或 hostvars 动态计算
- 所有后续任务、模板、handlers 都基于 group_names 判断,例如
{% if 'mysql_masters' in group_names %},逻辑清晰且可扩展
用 Jinja2 模板动态生成差异化配置
my.cnf 不是复制粘贴,是角色驱动的声明式输出。主库和从库的关键参数必须由模板自动开关,不能靠人工修改或启动后 set。
- 主库必须包含:
log-bin = /data/mysql/binlog/mysql-bin、binlog-format = ROW、skip-slave-start = 1 - 从库必须包含:
read_only = ON、relay-log = /data/mysql/relaylog/relay-bin、skip-slave-start = 0 - /etc/my.cnf 目标文件权限必须设为
0644,否则 mysqld 启动直接拒绝读取,日志仅报 “Failed to open config file”
初始化阶段严控用户、路径与权限
MySQL 8.0 起弃用 mysql_install_db,改用 mysqld --initialize-insecure,但该命令对属主和目录权限极其敏感。
- 执行前确保 /data/mysql 目录属主为 mysql 用户,且 mysql 用户对数据目录有完全读写权限
- 初始化命令需以 mysql 用户身份运行,不能用 root 直接执行再 chown,否则可能触发安全校验失败
- 初始化后首次启动前,必须确认 socket 文件路径、pid-file 路径在 my.cnf 中正确声明,且对应目录存在并可写
主从关系建立必须代码化、幂等化
CHANGE MASTER TO 不是手动敲一次就完事,它要嵌入 Playbook,且具备幂等判断——避免重复执行报错 “The slave I/O thread is running”。
- 使用
mysql_query模块执行 SQL,配合when: "'mysql_slaves' in group_names"限定仅从库执行 - 先查
SHOW SLAVE STATUS,若Slave_IO_Running != Yes再执行 CHANGE MASTER;已运行则跳过 - 复制账号(如 repl_user)必须在主库提前创建,并授予
REPLICATION SLAVE权限,密码通过 vault 加密管理
不复杂但容易忽略:自动化不是把手工步骤写成 YAML,而是把角色边界、配置逻辑、权限约束、执行顺序全部显性建模。一套能跑通的 Playbook,本质是一份可执行、可审计、可演进的集群契约。











