MySQL 主从复制中异常处理类问题

一、主从数据库数据不一致

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命令重新配置复制链路,这里需要注意的是文件和偏移量就是我们上面得到的两个值