事出有因
最近偶尔有客户反馈商品支付成功后订单还是待支付状态,可过一会便成功。这种数据不实时的情况对于分布式系统来说应该不是稀客,接到问题后天马行空了一番,难道是业务代码出bug?但也不科学呀!莫非是某同学SQL语句写的不友善,招mysql性能管家不待见?yy一番后到生产服务器一看,大吃一惊,select count(1) from order where order_id=xxx为0,无此订单,这不是荒谬吗?
目前线上mysql部署方案是一主两从,看来是主从同步出现了问题呀!问题定位后,下面便解决。
![57e74fdc1ea9f59cf6d2ff4f3f7887ea.png](https://i-blog.csdnimg.cn/blog_migrate/a508f7357a5250fb4be722cf2e0720f2.jpeg)
解决思路
两种方案
- 忽略错误,继续同步
- 记录错误原因及恢复依据
- 恢复同步
- 手动恢复被忽略的数据
- 重新做主从,完全同步
一、忽略错误,继续同步
该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况。对数据邀请严格也可在同步之后手动处理被忽略的数据。
解决过程:
1、记录错误原因及恢复依据
登录从节点,查看错误信息
show slave statusG;
记录下Relay_Master_Log_File、 Exec_Master_Log_Pos两个值。
登录主节点,根据Relay_Master_Log_File、 Exec_Master_Log_Pos查看同步异常的位置,如(此处Relay_Master_Log_File=‘mysql-bin.000001’,Exec_Master_Log_Pos=20544335):
![a92ffe778c5be04e60c21e2c00c3f913.png](https://i-blog.csdnimg.cn/blog_migrate/308d8178474f56672b7dac1af37656cf.jpeg)
可看到20544335开始到20544675截止事务结束,影响的表为eshop_user.user_login_log,后续同步重启将会跳过该事务,自动同步后需要再手动同步该表数据。
2、恢复同步
-- 登录从节点,停止数据同步stop slave;-- 表示跳过一步错误,后面的数字可变set global sql_slave_skip_counter =1;-- 启动start slave;-- 之后再用 show slave statusG 看到其中:-- Slave_IO_Running: Yes-- Slave_SQL_Running: Yes
则表示主从同步状态正常了。
3、手动恢复被忽略的数据
根据第1步骤的信息恢复数据。此处如何跟踪到具体哪条数据有异常,需要后续深入研究。最低效的处理方式是主从两个表做全量对比。
二、重新做主从,完全同步
该方法适用于主从库数据相差较大,或者要求数据完全统一的情况,但是先需要锁住主表,将会影响用户访问,正常情况不建议使用。
解决过程:
1、.先进入主库,进行锁表,防止数据写入
show master status;
2、进行数据备份
source /tmp/mysql.bakup.sql
3、查看master 状态
stop slave;
4、把mysql备份文件mysql.bakup.sql传到从库机器,进行数据恢复
source /tmp/mysql.bakup.sql
5、停止从库的状态
-- 注意该处的同步点,就是主库show master status信息里的File、 Position两项change master to master_host = '192.168.1.100', master_user = 'rsync_test', master_port=3306, master_password='', master_log_file = 'mysqld-bin.000001', master_log_pos=20544335;
6、从库执行mysql命令,导入数据备份
start slave;
7、设置从库同步
show slave statusG 查看:Slave_IO_Running: YesSlave_SQL_Running: Yes
8、重新开启-从同步
start slave;
9、查看同步状态
show slave statusG 查看:Slave_IO_Running: YesSlave_SQL_Running: Yes
同步完成!
问题出现原因
1、网络延迟(因为mysql主从同步是基于binlog的一种异步复制,通过网络传送binlog文件,理所当然网络延迟是主从不同步的绝大多数的原因)
2、主从两台机器的负载差异(因为mysql主从同步是主数据库上启动1个io线程,而从数据库上启动1个sql线程和1个io线程,其中任何一台机器的负载过高,导致其中的任何一个线程出现资源不足,都将出现主从不一致的情况)
![7574fd765b95d68ebc14fa67da4d19b9.png](https://i-blog.csdnimg.cn/blog_migrate/00f1d735755fcd7e874876558a70205e.jpeg)
mysql主从同步原理
3、max_allowed_packet设置不一致(主数据库上面设置的max_allowed_packet比从数据库大,当一个大的sql语句,能在主数据库上面执行完毕,从数据库上面设置过小,无法执行,导致的主从不一致)
4、mysql异常宕机情况下,如果未设置sync_binlog=1或者innodb_flush_log_at_trx_commit=1很有可能出现binlog或者relaylog文件出现损坏,导致主从不一致。
个人建议:日常开发中类似于这般对数据实时性有强要求的场景,可不需要强遵循主从原则。
![2ae0b723220a2bc98bf4e881a1bd7afc.png](https://i-blog.csdnimg.cn/blog_migrate/be592443cf12170e8b785adf567ac060.jpeg)
内容有参考,有自己的思考和总结,修行之路源于记录和不断地学习。