Ansible部署MySQL时mysql_user模块连不上新实例,因默认仅允许localhost连接;需显式指定login_host: 127.0.0.1、login_port: 3306,并确保skip-networking已禁用,root首次连接需login_password: ""。

Ansible 部署 MySQL 时 mysql_user 模块连不上新实例?
刚初始化的 MySQL 实例默认只允许 localhost 连接,mysql_user 模块若没显式指定 login_host 和 login_unix_socket,会尝试走 TCP 连接并失败——尤其在容器或非标准安装路径下。
- 用
login_host: 127.0.0.1强制走 TCP(绕过 socket 权限限制),配合login_port: 3306 - 若 MySQL 启动时禁用了 TCP(
skip-networking),必须先在my.cnf中注释掉该行再启动 - 首次连接 root 用户时,
login_password为空是正常行为;但 Ansible 会报Access denied,需加login_password: ""显式传空字符串
批量部署多个 MySQL 实例时,mysql_db 创建库总报 Unknown database
不是数据库不存在,而是当前连接用户没权限执行 CREATE DATABASE,或者目标实例未启用 sql_mode 兼容性设置(比如 strict mode 下对空库名敏感)。
- 确保
mysql_user任务中已为用户授予CREATE和GRANT OPTION权限,例如:priv: "*.*:ALL" -
mysql_db的name参数不支持变量拼接路径或动态前缀,如"{{ item }}_prod"要提前在 vars 中定义好,避免 Jinja2 渲染为空 - MySQL 8.0+ 默认开启
validate_password插件,若建库语句里带弱密码(如test123),会触发插件拦截,建议部署前用mysql_query关掉:ALTER SYSTEM SET validate_password.policy = LOW;
Ansible 执行 mysql_replication 模块失败:主从位点不一致、IO 线程未启动
常见于自动化脚本跳过了 GTID 校验或 binlog 格式检查。MySQL 5.7+ 默认 binlog_format=STATEMENT,但复制要求 ROW 或 MIXED,否则从库可能跳过某些变更。
- 在
mysqld配置中硬编码binlog_format = ROW,不要依赖运行时 set(Ansible 无法保证顺序) -
mysql_replication的mode: change_master不会自动启动 IO/SQL 线程,必须额外加mysql_replication: mode=start_slave任务 - 若主库已有数据,务必先
mysqldump --single-transaction --master-data=2导出,并在从库恢复后再执行 change master,否则Exec_Master_Log_Pos与实际不匹配
使用 community.mysql 插件集时 pip 安装失败或模块找不到
Ansible 2.10+ 已弃用内置 mysql_* 模块,必须手动安装社区插件包,且版本要和 MySQL 服务端兼容。常见错误是 ModuleNotFoundError: No module named 'mysql' 或 mysql_config not found。
- 在控制节点运行:
pip install mysqlclient(不是PyMySQL,后者不支持所有特性) - 确认系统有
mysql_config命令:Debian/Ubuntu 装libmysqlclient-dev,RHEL/CentOS 装mysql-devel - Ansible Playbook 开头必须声明:
collections:下写- community.mysql,否则即使 pip 装了也加载不到模块
GTID、SSL、SELinux 这几项一旦开启,Ansible 里的每个连接动作都得单独适配参数,不是加个 ssl_mode: REQUIRED 就完事——比如 mysql_user 要同步传 login_ssl_cert 和 login_ssl_key,漏一个就卡住。


















