Ansible生产部署MySQL集群必须物理隔离inventory分组、my.cnf.j2基于group_names动态配置角色、server-id全局唯一;任一缺失将导致Seconds_Behind_Master: NULL或ERROR 2003连接失败。

生产环境部署 MySQL 集群,不能靠“跑通 Playbook”交差,必须让 inventory 分组物理隔离、my.cnf.j2 模板基于 group_names 动态判断角色、server-id 全局唯一且不可硬编码——这三处错任意一个,集群大概率卡在 Seconds_Behind_Master: NULL 或直接报 ERROR 2003 (HY000): Can't connect to MySQL server。
inventory 必须硬拆 mysql_masters 和 mysql_slaves 组
Ansible 不会猜哪台是主、哪台是从,它只认你写进 group_names 的字符串。用 [dbservers] 一把抓再靠 when: inventory_hostname == 'db1' 判断,扩容时改主机名就得同步改几十处条件,极易漏。
-
[mysql_masters]只放 1 台(MGR 场景下可多台),用于写入 + 生成 binlog -
[mysql_slaves]放所有只读节点,用于拉取 relay log - 禁止用变量模拟角色,比如
slave: true;后续所有模板、任务、handlers 都应基于{% if 'mysql_masters' in group_names %}判断,而不是主机名或自定义变量
my.cnf.j2 模板里必须动态控制 log-bin、read_only 和 skip-slave-start
MySQL 主从行为由配置文件加载时决定,不是启动后靠 SQL 临时设的。写死参数或漏开关,会导致从库被写入、主库复制线程自启、或从库根本拉不到日志。
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
- 主库必须有:
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,不提示权限问题
优先用 community.mysql.mysql_community_server 模块而非手写 yum/apt
很多人一开始写 yum: name=mysql-server state=latest,结果在 CentOS 8+ 上失败(默认源无 mysql-server),或在 Ubuntu 上装成 MariaDB。根本原因是操作系统包名不统一,而 community.mysql 模块做了抽象适配。
- 必须先安装 collection:
ansible-galaxy collection install community.mysql - Playbook 中调用时指定
name: community.mysql.mysql_community_server,不是mysql或mysql-server - 该模块自动判断系统类型,安装对应二进制包(RHEL 用官方 RPM,Ubuntu 用 APT 源里的
mysql-community-server) - 不推荐再用
shell或command手动执行mysqld --initialize-insecure——模块已内置初始化逻辑,且支持root_password参数安全设密
首次连接 MySQL 必须用 login_unix_socket,不能只靠 login_user/login_password
MySQL 5.7+ 默认禁用空密码 root 登录,且首次启动后 localhost 的 root 只能通过 socket 认证。Ansible 连不上刚装好的 MySQL,90% 是因为没传 login_password,或误设 login_user: root 却没配密码。
- 首次部署后连接必须显式指定:
login_unix_socket: /var/run/mysqld/mysqld.sock(RHEL/CentOS)或/var/run/mysqld/mysqld.sock(Ubuntu/Debian) - 若要允许远程
root登录,得额外加 task 调用mysql_user模块显式授权:host: "%"+priv: "*.*:ALL",不能指望安装过程自动开 - 忽略
ignore_errors: True在数据库任务里——它会让密码错误静默失败,后续任务全崩 - 配置文件覆盖必须用
template+notify,别直接copy覆盖my.cnf;否则会清掉系统自带的include目录(如/etc/my.cnf.d/),导致启动报 “unknown variable”
真正难的不是写完 Playbook,而是确保每台机器的 datadir 属主是 mysql:mysql、mysqld --initialize-insecure 由 mysql 用户执行、且目录为空——这些细节一旦漏检,服务就起不来,连日志都看不到明确报错。

















