广告位 · 页头(后台-模块管理-新建模块后替换此区域)

MySQL主从密码怎么同步?主从复制账号密码修改配置方法

在MySQL主从复制架构中,密码同步并不是一个统一动作,它至少涉及两类账号:一类是业务账号,也就是应用程序读写数据库使用的账号;另一类是复制账号,由从库的IO线程连接主库拉取binlog时使用。两类账号的密码修改后,同步路径完全不同。业务账号的ALTER USER语句会被记录到binlog并传递到从库,因此主库改完,从库也会自动出现同样的密码变化;但复制账号的密码只存在于从库的复制连接配置中,主库修改后,从库不会自动感知,IO线程还会拿旧密码反复重连,最终表现为Slave_IO_Running为Connecting或直接报Access denied。本文重点解决后一种情况,同时顺带说明业务账号密码在从库上的表现,避免混淆。

MySQL主从密码怎么同步?主从复制账号密码修改配置方法

一、先分清业务账号密码和复制账号密码

业务账号的密码修改,本质上是一条DCL语句。比如在主库执行ALTER USER 'app_user'@'%' IDENTIFIED BY 'NewAppPass';,这条语句会被写入binlog。从库的SQL线程读取binlog后在本地重放,从库的mysql.user表也会同步更新,因此应用连接从库时就能使用新密码。这个同步过程与binlog_format设置关系不大,即使设置为ROW模式,DCL语句仍然以语句形式记录。换句话说,只要主从复制链路本身正常,业务账号密码的同步通常不用人工干预。

复制账号则不同。从库连接主库时,需要提供主库的地址、端口、用户名和密码。这些连接信息在从库执行CHANGE MASTER TO或CHANGE REPLICATION SOURCE TO时被保存下来,写入内存以及持久化到master.info文件或mysql.slave_master_info表。主库修改复制账号密码后,从库本地保存的凭据不会自动变化,IO线程还是用旧密码去连接主库,主库校验失败,从库就会报错。这个机制听上去简单,但实际故障中很容易被误判成主从数据不一致或网络问题。

可以通过下面的SQL查看从库当前保存的复制连接信息。如果配置了master_info_repository=TABLE,可以查询mysql.slave_master_info表;如果是FILE方式,则查看数据目录下的master.info文件。密码字段通常不是明文,所以不要指望直接从表里读出旧密码,重点是确认用户和主机信息是否正确。

SELECT HOST, USER_NAME, USER_PASSWORD, SSL_VERIFY_SERVER_CERT
FROM mysql.slave_master_info;

二、修改主库复制账号密码并同步到从库

假设主库地址为192.168.1.101,从库地址为192.168.1.102,复制账号为repl,旧密码是OldPass@123,新密码准备改为NewPass@456。第一步在主库修改复制账号密码。如果主库是MySQL 8.0,默认身份验证插件是caching_sha2_password,从库连接时可能需要SSL或公钥支持。为了减少变量,不少环境仍使用mysql_native_password,但MySQL 8.0.34之后已经弃用,新部署建议直接使用caching_sha2_password并配置好安全连接。

-- 主库执行
ALTER USER 'repl'@'%' IDENTIFIED BY 'NewPass@456';
FLUSH PRIVILEGES;

接着在从库停止复制。MySQL 8.0.22及之后的版本推荐使用STOP REPLICA,旧版本使用STOP SLAVE。停止复制是为了避免IO线程在修改连接信息的过程中继续用旧密码重连,也避免SQL线程继续回放产生并发操作。如果只想停止IO线程,可以执行STOP REPLICA IO_THREAD;,但完整停止再修改会更稳妥。

-- 从库执行,停止复制
STOP REPLICA;
-- MySQL 5.7可执行
STOP SLAVE;

然后更新从库连接主库时使用的密码。MySQL 5.7使用CHANGE MASTER TO,MySQL 8.0推荐使用CHANGE REPLICATION SOURCE TO。如果只改密码,写一个密码参数即可;如果主机、端口、用户、二进制日志位置也需要调整,可以同时指定。基于GTID复制的环境不需要指定SOURCE_LOG_FILE和SOURCE_LOG_POS,MySQL会自动根据GTID集合继续拉取。

-- MySQL 8.0推荐写法
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.1.101',
  SOURCE_USER='repl',
  SOURCE_PASSWORD='NewPass@456',
  SOURCE_PORT=3306;
-- MySQL 5.7兼容写法
CHANGE MASTER TO
  MASTER_HOST='192.168.1.101',
  MASTER_USER='repl',
  MASTER_PASSWORD='NewPass@456',
  MASTER_PORT=3306;

修改完成后启动复制。启动后不要立刻认为成功,必须通过状态视图确认IO线程和SQL线程均为Yes。如果IO线程状态是Connecting,说明还在连接中或者密码仍然不对;如果报Access denied,说明从库保存的密码和主库不一致,需要重新检查参数。Seconds_Behind_Master为0通常表示当前没有明显延迟。

-- 启动复制
START REPLICA;
-- MySQL 5.7
START SLAVE;
-- 查看状态
SHOW REPLICA STATUS\G
-- MySQL 5.7
SHOW SLAVE STATUS\G

这里有一个容易忽略的细节:CHANGE REPLICATION SOURCE TO本身不会校验新密码是否正确,它只是把字符串保存到从库连接配置中。只有启动复制后,IO线程真正连接主库时,才会触发身份验证。因此改完密码后一定要等几秒看状态,不要执行完语句就离开。

三、用配置文件和持久化表管理复制连接

从库重启后,复制连接信息从哪里读取,取决于master_info_repository和relay_log_info_repository两个参数。建议将它们设置为TABLE,这样连接信息会写入InnoDB表,避免文件损坏导致复制配置丢失。在从库的my.cnf中可以加入如下配置。其中skip_slave_start或skip_replica_start的作用是让从库启动时不自动启动复制线程,防止使用旧密码或旧位置直接重连主库。

[mysqld]
server-id=2
relay-log=relay-bin
read_only=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
skip_replica_start

如果不想每次手动执行CHANGE REPLICATION SOURCE TO,可以准备一个初始化SQL脚本,在从库首次部署或重启后执行。脚本内容与第二节的命令一致,但要注意密码不要以明文形式长期存放在共享目录。更安全的做法是通过配置管理工具注入环境变量,或者使用MySQL的密钥环组件保存敏感信息。实践中,不少团队会把复制账号密码放在运维平台的配置中心,部署时渲染成临时SQL文件,执行完成后立即删除。

另一个常被忽略的问题是业务账号密码在从库上的可读性。从库通常设置为read_only=ON,但SQL线程执行主库传来的ALTER USER语句时不受只读限制。因此主库修改业务账号密码后,从库会自动同步,不需要手动在从库重复执行ALTER USER。只有复制账号这类用于建立主从连接的凭据,才必须通过从库本地命令更新。

四、验证结果与常见报错排查

验证主从密码同步是否完成,最直接的方式是查看复制状态。关注Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master三个字段。如果是基于GTID的复制,还可以查看Retrieved_Gtid_Set和Executed_Gtid_Set判断从库是否已经拉取并执行了主库新产生的binlog。下面是一个正常状态的示例。

SHOW REPLICA STATUS\G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for source to send event
                  Source_Host: 192.168.1.101
                  Source_User: repl
                  Source_Port: 3306
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0

如果看到Last_IO_Error中出现Access denied for user 'repl'@'192.168.1.102' (using password: YES),基本可以确定是密码错误或授权主机不匹配。先确认主库上复制账号的授权范围,例如执行SHOW GRANTS FOR 'repl'@'%';。如果创建账号时只允许某个固定IP,而后来从库IP发生了变化,即使密码正确也会被拒绝。授权范围与密码同步一样,都需要和复制账号配置保持一致。

主库使用caching_sha2_password插件时,还可能遇到Authentication plugin 'caching_sha2_password' cannot be loaded或SSL相关错误。这种问题的根源不是密码本身,而是从库IO线程在首次认证时拿不到主库的公钥。解决办法有两种:一是为复制连接启用SSL,在CHANGE REPLICATION SOURCE TO中增加SOURCE_SSL=1及相关证书参数;二是将复制账号改为mysql_native_password插件,例如ALTER USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'NewPass@456';。不过从长期维护角度,启用SSL并在主库开启公钥获取参数会更稳妥。

如果修改密码并启动复制后仍然报错,建议先绕过复制线程,在从库本机手工测试连接主库。执行mysql -h192.168.1.101 -urepl -p'NewPass@456' -e "SELECT 1;",观察是否能正常返回。这样可以把问题范围缩小到复制参数、网络或账号权限。确认手工连接成功后,再回头检查从库的连接信息是否真的更新成功,避免因为缓存或配置文件优先级造成干扰。

最后提醒一点,主从密码同步的关键不是把密码复制到从库,而是让从库知道连接主库时应该使用哪个新密码。只要分清楚业务账号和复制账号的同步路径,修改配置和排错的思路就会清晰很多。

广告位 · 文章底部(后台-模块管理替换此区域)