ansible部署mysql集群失败主因是主从角色不清、server-id重复、初始化权限错、mysql_user连不上;须按inventory分组定义角色,模板动态配置参数,严格校验路径权限及python解释器。

直接上 Playbook 不能让 MySQL 集群跑起来。主从角色没分清、server-id 重复、mysqld --initialize-insecure 权限不对、mysql_user 连不上新实例——这四类问题占了 Ansible 部署失败的 80% 以上。
inventory 必须按角色分组,不能只写 [dbservers]
Ansible 不会自己猜哪台是主、哪台是从。全靠 inventory 分组驱动后续所有逻辑分支:
-
[mysql_masters]:只能有 1 台,负责写入 + 生成 binlog;server-id统一设为100 -
[mysql_slaves]:可多台,只读 + 拉取 relay log;server-id用递增整数,如201、202 - 变量不能硬编码进
vars/main.yml,否则扩容时要改代码;推荐用host_vars/或 group_vars 下按组定义 - 银河麒麟 V10 节点需额外加
ansible_python_interpreter: /usr/bin/python3,否则模块报错ModuleNotFoundError: No module named 'mysql'
my.cnf.j2 模板里必须用 group_names 判断角色
Jinja2 模板不能写死 log-bin 或 read_only,否则主库被设成只读、从库没开 relay log,同步直接卡死:
- 主库必须设
skip-slave-start = 1,防止误启复制线程干扰初始化 - 从库必须设
read_only = ON,否则手动写入会破坏数据一致性 -
datadir和socket路径要和实际部署目录严格一致,/etc/my.cnf文件权限必须是644,否则mysqld启动时报 “Failed to find valid data directory” - MySQL 8.0+ 默认启用
validate_password,建库前建议用mysql_query执行SET GLOBAL validate_password.policy = LOW
mysql_user 模块连不上新实例?检查 login_host 和 skip-networking
刚初始化的 MySQL 实例默认只监听 localhost socket,mysql_user 模块默认走 TCP,不指定 host 就会连不上:
- 显式写
login_host: 127.0.0.1+login_port: 3306,绕过 socket 权限限制 - 确认
my.cnf中没有skip-networking,否则必须注释掉再启动服务 - 首次连接 root 用户时,
login_password: ""必须显式传空字符串,否则报Access denied - 若用
community.mysql插件集,控制节点必须pip install community.mysql==3.12.0(适配 MySQL 8.0.33+)
mysqld --initialize-insecure 执行失败的三个硬性条件
这个命令对用户、路径、参数极其敏感,错一个就报 Failed to find valid data directory 或静默失败:
- 必须用
mysql用户执行,不能用root直接跑;Ansible 任务中加become_user: mysql -
datadir目录(如/data/mysql)必须提前chown -R mysql:mysql /data/mysql - 命令必须带
--user=mysql和--basedir=/usr(或对应安装路径),否则找不到插件目录 - 执行后不会生成临时密码,适合自动化场景;但后续
mysql_user创建账号时,得确保root@localhost已存在且可用
最易被忽略的是:MySQL 8.0 的 binlog_format 默认是 ROW,但 Ansible 任务里如果没在配置文件中硬编码,而是依赖运行时 SET,就可能因执行顺序问题导致从库 IO 线程启动失败。别信“先启服务再改配置”的惯性思维——配置必须在第一次启动前就落盘。











