MySQL半同步复制工作原理
- 主库操作:
- 当主库执行完一个事务,写入二进制日志(binlog)后,并不会立刻返回给客户端事务执行成功的响应。
- 主库会等待至少一个从库接收并将接收到的日志写入其中继日志(relay log)。
- 从库操作:
- 从库通过I/O线程连接主库,接收主库发送的二进制日志,并将其写入中继日志。
- 从库成功写入中继日志后,会向主库发送一个ACK确认消息。
- 完成事务确认:
- 主库在收到至少一个从库的ACK确认后,才会向客户端返回事务执行成功的响应,同时将该事务标记为已提交。如果在一定时间内(由参数
rpl_semi_sync_master_timeout
控制,默认10000毫秒,即10秒)没有收到从库的ACK确认,主库会切换回异步复制模式继续工作,以避免阻塞主库的事务处理。
从库故障导致无法正常同步的排查和解决方法
- 网络层面排查:
- 检查网络连接:使用
ping
命令检查主从库之间的网络是否连通。如果不通,排查网络设备(如路由器、防火墙等)的配置,确保主从库之间的端口(默认MySQL端口3306)是开放的。
- 检查网络延迟:使用
traceroute
命令查看网络路由情况,判断是否存在网络延迟过高的问题。如果延迟过高,联系网络管理员优化网络路径。
- MySQL配置排查:
- 检查主库配置:确认主库的
log - bin
参数是否开启,以及server - id
是否配置正确且唯一。例如:
[mysqld]
log - bin = /var/log/mysql/mysql - bin.log
server - id = 1
- 检查从库配置:检查从库的
server - id
是否与主库不同且唯一,以及relay - log
等相关参数配置是否正确。例如:
[mysqld]
server - id = 2
relay - log = /var/log/mysql/mysql - relay.log
- 检查复制账号权限:在主库上,确保为从库配置的复制账号具有正确的权限。可以使用以下命令查看和修改权限:
-- 查看复制账号权限
SHOW GRANTS FOR'replication_user'@'slave_host';
-- 赋予复制权限
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'slave_host' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
- 从库状态排查:
- 查看从库复制状态:在从库上执行
SHOW SLAVE STATUS \G
命令,重点关注以下几个参数:
Slave_IO_Running
和Slave_SQL_Running
:如果这两个参数的值为No
,说明I/O线程或SQL线程有问题。如果Slave_IO_Running
为No
,可能是网络问题或复制账号权限问题;如果Slave_SQL_Running
为No
,可能是中继日志应用过程中出现错误。
Last_IO_Errno
和Last_IO_Error
:这两个参数记录了I/O线程的错误信息。根据错误信息进行针对性解决,如网络连接问题、主库配置变更导致从库无法识别等。
Last_SQL_Errno
和Last_SQL_Error
:这两个参数记录了SQL线程的错误信息。常见错误如主从库数据不一致、表结构不一致等。如果是数据不一致,可以尝试通过重新搭建从库或使用合适的数据同步工具进行修复;如果是表结构不一致,需要在主从库上统一表结构。
- 日志排查:
- 主库二进制日志:查看主库的二进制日志文件(
log - bin
指定的文件路径),确认主库是否正常记录事务日志。如果日志记录异常,可能是主库的磁盘空间不足等问题导致。
- 从库中继日志:查看从库的中继日志文件(
relay - log
指定的文件路径),确认从库是否正常接收主库的日志。如果中继日志为空或接收不完整,可能是网络问题或从库I/O线程故障。可以尝试重启从库的I/O线程(执行STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
)。
- 解决方法:
- 重启复制线程:如果是一些临时性的故障,可以尝试在从库上重启复制线程。执行
STOP SLAVE; START SLAVE;
命令,重新启动I/O线程和SQL线程,看是否能恢复同步。
- 重新搭建从库:如果从库故障严重,无法通过常规方法修复,可以考虑重新搭建从库。先在主库上执行
FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS;
获取主库的二进制日志文件名和位置,然后在从库上停止复制,重置复制设置(RESET SLAVE;
),再根据主库信息配置从库(CHANGE MASTER TO...
)并启动复制(START SLAVE;
)。