一、主从数据库数据不一致
1、问题描述
首先确认主从数据库延迟为0,并且IO_THREAD和SQL_THREAD均未YES。
但是相同的查询在主从服务器中查询结果就是不一样。
2、原因分析
(1)有人对从服务器进行了写操作
(2)处理异常时,使用了sql_slave_skip_counter或注入空事务的方式来修复错误
(3)使用了statement格式的复制
statement格式的复制是执行master相同的sql,而row格式的复制时应用master相同的sql。
区别在于,如果是uuid()这样的函数,使用statement格式的复制就会导致执行结果不一致,而使用row格式的复制,因为执行的是同样的sql语句,结果肯定是一致的。
3、解决方案
(1)在slave实例上设置read_only=ON
(2)5.7版本以上,还要在slave上设置super_read_only=ON
(3)改为使用row格式的复制
row格式记录了在master上的实际修改,然后在slave上直接应用。
(4)使用pt_table_sync修复数据
pt_table_sync \
--execute \
--charset=utf8 \
--database=stock \
--sync-to-master \
h=192.168.78.103,u=dba,p=123456
注意:这里的h、u、p跟的是slave的host、用户、密码,而不是master的。
二、slave连接不上master
1、问题描述
slave_IO_Running状态是connecting,slave_SQL_Running状态是yes
但Last_IO_Error报出了错误信息,连接不上master。
2、原因分析
(1)主从服务器之间网络不畅通
(2)master存在防火墙,过滤了数据库端口
(3)复制链路配置的用户名和密码不正确,或没有相应权限
3、解决方案
(1)确定主从之间网络畅通
ping master_IP
(2)确定是否可以正常访问master端口
telnet master_IP MySQL端口号
(3)确定复制链路使用的用户名密码是否可以连接到master
mysql -u用户名 -p密码 -h master_IP
(4)确定是否有复制同步权限
# 查看当前登录用户的权限
show grants for current_user;
# 如果没有复制权限,则应登录MySQL root账户为复制账户添加相应权限
grant replication slave on *.* to 复制账户
# 在slave上执行停止slave
stop slave;
在slave上执行开启slave
start slave;
三、主从复制中,主键冲突
1、问题描述
通过show slave status \G 获取到,slave_IO_Running为YES状态,但slave_SQL_Running为No状态。
并且last_error报主键冲突错误
2、原因分析
(1)有人操作了slave中的数据
(2)slave出现过宕机,由于默认情况下,relay-log的信息是保存在文件中,所以可能在slave宕机时,已经执行的并没有保存在日志中,slave重启后,又执行了重复的日志,就造成了主键冲突
3、解决方案
方式1:直接删除从库主键冲突数据,重启slave【推荐方案】
方式2:跳过错误,然后使用pt_table_sync修复数据。
四、数据行不存在
1、问题描述
通过show slave status \G 获取到,slave_IO_Running为YES状态,但slave_SQL_Running为No状态。
并且last_error报can't find record错误
2、原因分析
(1)有人在slave删除了数据
(2)之前处理主从故障时,使用了跳过错误或置入空事务方式解决造成数据在slave上的丢失
3、解决方案
然后使用pt_table_sync修复数据
五、relay_log损坏
1、问题描述
通过show slave status \G 获取到,slave_IO_Running为YES状态,但slave_SQL_Running为No状态。
并且last_error报error initializing relay log position错误
2、解决方案
# 找到已经正确同步的日志点
show slave status \G
# 在结果集中找到 Relay_Master_Log_File 和 Exec_Master_Log_Pos
# 使用reset slave 命令删除relay_log
# 使用change master命令重新配置复制链路,这里需要注意的是文件和偏移量就是我们上面得到的两个值