一、问题/场景描述
在搭建MySQL主从复制架构时,经常遇到从库无法连接主库,报错“权限拒绝”(Access denied for user)。具体表现为:从库执行CHANGE MASTER TO语句后,启动从库复制线程时,错误日志中出现类似“Last_IO_Error: error connecting to master ‘repl@ip:port’ – Access denied for user ‘repl’@‘slave_ip’ (using password: YES)”的信息。该问题导致主从数据无法同步,影响数据库高可用方案的正常运行。
二、原因分析
MySQL主从复制权限拒绝的根本原因通常是主库上用于复制的用户账号权限配置不正确。主要包括:
- 主库上未创建专用的复制用户,或用户密码错误。
- 复制用户缺少
REPLICATION SLAVE权限。 - 主库的
host字段限制过严,未允许从库IP地址连接。 - 主库的
bind-address配置只监听本地地址,拒绝远程连接。 - 防火墙或网络策略阻止从库访问主库的MySQL端口(默认3306)。
- 主库的
skip-grant-tables模式导致权限表异常。
最常见的原因是用户权限授予语句未正确执行,或从库连接时使用了错误的用户名/密码。
三、详细解决步骤
步骤1:检查主库复制用户是否存在及权限
在主库上登录MySQL,执行以下命令查看现有用户:
SELECT user, host FROM mysql.user WHERE user = 'repl';
如果返回空结果,说明未创建复制用户。需执行以下命令创建用户并授予权限:
CREATE USER 'repl'@'从库IP' IDENTIFIED BY '密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从库IP';
FLUSH PRIVILEGES;
注意:从库IP需替换为实际的从库服务器IP地址,或使用%通配符(不推荐,存在安全风险)。
步骤2:验证主库的bind-address配置
在主库上检查MySQL配置文件(通常位于/etc/my.cnf或/etc/mysql/my.cnf):
grep bind-address /etc/my.cnf
如果值为127.0.0.1,则只允许本地连接。需修改为0.0.0.0或主库实际IP地址:
bind-address = 0.0.0.0
修改后重启MySQL服务:
systemctl restart mysqld
步骤3:测试从库到主库的网络连接
在从库上使用telnet或mysql命令测试连通性:
telnet 主库IP 3306
如果连接失败,检查防火墙规则:
iptables -L -n | grep 3306
必要时添加允许规则:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
步骤4:在从库上重新配置主从复制
在从库上登录MySQL,停止复制线程并重新配置:
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='密码', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
注意:MASTER_LOG_FILE和MASTER_LOG_POS需从主库的SHOW MASTER STATUS;获取。
START SLAVE;
步骤5:检查复制状态
在从库上执行:
SHOW SLAVE STATUSG
重点关注以下字段:
Slave_IO_Running: YesSlave_SQL_Running: YesLast_IO_Error: 空
如果仍然报权限拒绝,请检查主库的mysql.user表,确认用户密码是否匹配:
SELECT user, host, authentication_string FROM mysql.user WHERE user = 'repl';
四、注意事项
1. 创建复制用户时,务必指定正确的从库IP地址,避免使用%通配符带来的安全隐患。
2. 修改bind-address后需重启MySQL服务,否则配置不生效。
3. 主从复制使用的密码应遵循强密码策略,并定期更换。
4. 如果主库启用了skip-grant-tables,必须先关闭该模式,否则所有权限验证都会失败。
五、适用环境
本文适用于主流Linux发行版(CentOS 7 / Ubuntu 22.04)+ MySQL 5.7 / 8.0 环境。
