必须将 inventory 物理拆分为 mysql_masters 和 mysql_slaves 两组,主库仅1台(MGR可多台)负责写入与 binlog,从库全放只读节点拉 relay log;my.cnf.j2 中 log-bin/read_only/skip-slave-start 等需按组动态配置,server-id 全局唯一(主库100、从库201+),/etc/my.cnf 权限须为644,初始化用 mysqld --initialize-insecure 并以 mysql 用户执行,之后立即用 mysql_user 模块设强密码。

必须硬拆 inventory 分组,否则主从角色逻辑必然错乱。 Ansible 不识别“主库”“从库”语义,只认 group_names 列表里的字符串;靠 when: inventory_hostname == 'db1' 这类主机名判断,扩容时改一处就得漏十几处,集群大概率卡在 Seconds_Behind_Master: NULL 或直接报 ERROR 2003 (HY000): Can't connect to MySQL server。
inventory 必须物理拆成 mysql_masters 和 mysql_slaves
这是所有后续逻辑的起点,错一步全盘失效:
-
[mysql_masters]只放 1 台(MGR 场景可多台),用于写入 + 生成 binlog -
[mysql_slaves]放所有只读节点,用于拉 relay log - 绝对不要用
[dbservers]一把抓再靠变量分支——Ansible 的group_names是运行时注入的只读列表,无法被任务动态修改 - Playbook 中的
hosts:必须明确指向这两个组,例如:- hosts: mysql_masters和- hosts: mysql_slaves
my.cnf.j2 模板里 log-bin / read_only / skip-slave-start 必须动态判断
MySQL 主从行为由配置加载时锁定,不是启动后靠 SQL 临时设的。写死或漏设,会导致从库被写、主库复制线程自启、从库根本拉不到日志:
- 主库段必须包含:
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 -
server-id必须全局唯一:主库固定为100,从库用201、202等递增整数,不能全写1 -
/etc/my.cnf目标文件权限必须是644,否则mysqld启动时静默拒绝读取,日志只报Failed to open config file
mysqld --initialize-insecure 对用户和目录属主极其敏感
MySQL 8.0+ 已弃用 mysql_install_db,改用 mysqld --initialize-insecure,但它不校验密码,却严查运行上下文:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 命令必须由
mysql用户执行,不能用root直接跑 -
/data/mysql目录需提前chown -R mysql:mysql /data/mysql - 命令必须显式加
--user=mysql和--basedir参数,否则报Failed to find valid data directory - Ansible 任务中应使用
become_user: mysql+shell:模块调用,并确保datadir路径与模板中一致
初始化后必须立刻用 mysql_user 模块设强密码
--initialize-insecure 跳过临时密码生成,适合自动化,但留空 root 密码是生产大忌:
- 不能依赖首次登录后手动设密码,必须在 Playbook 中紧接初始化步骤之后调用
mysql_user模块 - 注意:该模块要求 MySQL 服务已启动且 socket 可达,所以
service: name: mysqld state: started必须在mysql_user前执行 - 若用 TCP 连接,需确保
bind-address未设为127.0.0.1,且防火墙放行3306 - GTID 场景下,还需在主库执行
SET GLOBAL enforce_gtid_consistency = ON和SET GLOBAL gtid_mode = ON_PERMISSIVE,这些不能写进 my.cnf.j2,得用mysql_query模块单独跑
最易被忽略的是 /etc/my.cnf 权限和 server-id 全局唯一性——前者导致启动失败无提示,后者引发复制中断却无明显报错;这两点在批量部署中一旦出问题,排查成本远高于重跑一次 Playbook。










