MYSQL主从同步故障的问题分析与解决方法

发布时间:2020-03-18编辑:脚本学堂
本文介绍下,我遇到的一例mysql主从同步故障,有相关的原因分析与解决方法,供遇到类似问题的朋友作个参考。

本节主要内容:
mysql主从同步故障的解决方法

在mysql中查询主从同步信息:
 

show slave status G; 果然
Slave_IO_Running: Yes
Slave_SQL_Running: No
 

出现了1062错误,提示:
Last_SQL_Error: Error 'Duplicate entry '1001-164761-0' for key 'PRIMARY'' on query. Default database: 'bug'. Query: 'insert into misdata (uid,mid,pid,state,mtime) values (164761,1001,0,-1,1262623560)'

很显然,由于主库重启导致 从库数据不同步而且主键冲突。
查看error 日志发现error日志文件变得好大,比以前大了将近好几倍,
tail -f mysql_error.log

最开始查看到的是这条信息:
 

 [ERROR] Slave SQL: Error 'Duplicate entry '1007-443786-0' for key 'PRIMARY'' on query. Default database: 'ufo'. Query: 'insert into misdata (uid,mid,pid,sta
te,mtime) values (443786,1007,0,-1,1262598003)', Error_code: 1062
100104 17:39:05 [Warning] Slave: Duplicate entry '1007-443786-0' for key 'PRIMARY' Error_code: 1062
100104 17:39:05 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'ufolog.000058
8' position 55793296


报错和上面的意思差不多,

首先手动同步一下,从库上首先 stop slave;停止同步
进入主库锁表,
 

复制代码 代码示例:
FLUSH TABLES WITH READ LOCK;
mysql> show master status;
+-------------------+-----------+--------------+------------------+
| File              | Position  | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+-----------+--------------+------------------+
| ufo.000063 | 159164526 |              |                  |
+-------------------+-----------+--------------+------------------+
1 row in set (0.00 sec)

进入从库
 

复制代码 代码示例:
mysql>change master to master_host='192.168.1.141', master_user='slave',
master_password='xxx',
master_port=3306,
master_log_file='ufo.000063',
master_log_pos=159164526;
 

完成以上操作。

start slave;
回到主库
unlock tables; 解锁

回到从库 查看
show slave status G;

发现正常了,可是还没过一分钟,发现又开始报错了,还是最开始那个错误。
于是又想到了跳过错误的办法,马上进入从库
 

复制代码 代码示例:
stop slave;
set global sql_slave_skip_counter=1; (1是指跳过一个错误)
slave start;
 

再show slave status G;查看
还是报错 只不过 原来的 164761 变成了 165881,连续执行了几次后
除了上面的数值 在变,错误依然还在。

看来只能先强制跳过 1062错误了,于是修改从库的/etc/my.cnf文件
在[mysqld]下面加入此行:
slave-skip-errors = 1062 (忽略所有的1062错误)

重启下从库:
mysql /etc/init.d/mysqld restart
再 show slave status G;一下发现正常了,但是我知道这时的数据可能已经不同步了,

再次查看一下日志,让我感到意外的是tail -f mysql_error.log 出现大量的
.......
100106 16:54:21 [Warning] Statement may not be safe to log in statement format. Statement: delete from `system_message_1` where `to_uid` = 181464 ORDER BY `id` ASC LIMIT 1
.........
日志里面有大量的这种警告,statement 格式不安全,用vim 打开他看了一下,发现好多这类警告!
statement format 应该是 binlog的一种格式,进入从库查看一下
show global variables like 'binlog_format';
果然当前的格式为statement
需要把格式改为 mixed格式

修改从库的 my.cfg
在[mysqld]中添加:
binlog_format=mixed

然后,重启mysql服务,发现错误日志里的 警告 都停止了。这回清静多了~~

有朋友说过 RBR 模式可以解决很多因为主键冲突导致的主从无法同步情况,想到这里我就想要不要把 slave-skip-errors = 1062 去掉再试试,
于是,进入到my.cnf 里在注释掉了 slave-skip-errors = 1062
再次重新启动 mysql服务
进入从库
 

复制代码 代码示例:
show slave status G;
.........              
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
 

恢复正常了,一段时间后依然是正常的,看来问题成功解决了。

>>> 更多内容,请访问:mysql主从复制、mysql主从同步系列教程

相关阅读:
Mysql 主从复制(Replication)的实例分享
mysql主从同步设置的实例参考
mysql5.5主从复制(Replication)的简单配置示例
mysql主从复制安装与配置一例
mysql 主从数据库配置一例(图文)
mysql 主从同步一例
mysql主从简明配置一例
mysql主从复制读写分离的实现方法
MySQL主从服务器配置的一些总结
配置mysql主从时的注意事项
简单配置mysql的主从复制
windows下mysql主从复制配置
centos5.4下mysql主从复制配置分享
linux下mysql主从同步复制配置