刚接手一个新库,收到前端反应,有一个权限变更后不能生效(实际上是过8-10秒后才能看到变更后的正确数据),经排查,发现是主从同步延迟导致。
这里就不讲主从同步原理了,先讲一下定位主从同步延迟问题的基本套路:
问题发生在master上,去看processlist,看slowsql,看操作系统负载,看系统参数配置;
问题发生在slave上
SQL thread慢,表现是:
Seconds_Behind_Master越来越大
Slave_SQL_Running_State: Reading event from the relay log
b. IO thread慢,表现是:
Seconds_Behind_Master为0
Slave_SQL_Running_State: 显示正常值
Slave_IO_State:显示忙碌状态
我这边在slave看到的是:
Slave_IO_State: Waiting for master to send event
Seconds_Behind_Master: 0
Slave_SQL_Running_State: Waiting for dependent transaction to commit
也就是说,事务压根还没到slave来,那就是卡在master那边了,为了进一步验证,我做了mysqlbinlog,截取了主库的binlog和从库的relaylog,下图是主库的binlog信息,由于主库的binlog是row模式,做了base64的decode显示如下
但是在从库同时期对应的relaylog中,找不到对应的事务
(第一次看到binlog的时候,我很好奇为什么这个事务这么大,截图不全,上图这样的内容有500行左右,可以说很大了,后面会提到)
现在基本明确,问题在master上面了,首先看了负载,很低,不会对这种非并发操作造成影响,接着联系前端同事操作看了processlist,发现有一些sql在列表中停留了好一会,那就去看看slowlog
抓到slowsql,看到top1跟前面processlist里面看到的sql是同一个,让前端同事再跑了一遍,自己又抓了一遍slowlog,惊讶的发现该sql的count多了38次!也就是说修改一个权限要把这个select跑38遍之多!经与研发确认,该业务修改这个页面上的一个权限,会把这个页面的全部数据都校验-删除-插入走一遍,所以前面的binlog中事务那么大也就不奇怪了。
现在就不纠结业务的问题还是研发的问题了,解决问题吧,查看执行计划,发现是全表扫描,分析表数据后,发现两个查询条件的组合键还不错,创建了一个索引,问题就此解决。
最后想说,这个sql本身效率不算低,但架不住执行次数多啊~
领取专属 10元无门槛券
私享最新 技术干货