一、背景
突然发现每天中午以及下午的延时变高,查看主从的延时经常达到10分钟以上,整体使用的是mysql-proxy实现的读写分离机制,所以业务的影响主要是插入数据后久久不能查询到数据。
由于使用mysql业务比较多,一时之间不能快速定位,导致该问题存在的较长时间。
二、解决思路
1.到了案发时间,下午16点半,直接登陆从库查看进程情况,查找耗时较长的数据表&语句
2.定位到查询语句,查看表结构+表的数量,发现存在三个问题:
(1)使用的MyISAM引擎
(2)表中数据达到500w+,存放的是用户操作记录,最早的数据是2018-10的,即大量无用数据
(3)未命中索引,进行全表查询
3.解决方案:
(1)清理年代久远的数据,只保留近3个月的操作记录,数据量一下减少到30w左右
(2)将引擎修改为InnoDB,将原本的表级锁改为行级锁
(3)优化查询语句,充分利用索引
4.验证
运行查询语句的定时脚本,脚本迅速跑完,主从延时不超过5s,可以证明该问题已经解决。
三、刨根问底
问题确实解决了,主要原因就是引擎&查询语句导致的耗时较长,但是令人疑惑: 按理说MyISAM锁表也就锁这一张表呀,为啥会导致大量业务也有问题了呢?
通过查找资料终于找到了结果:
(1)使用的是mysql-proxy的读写分离功能,写是写到主库,读是查询从库,主库要定时同步到从库
(2)主从同步的机制:主库针对读写操作,顺序写 binlog,从库单线程去主库读"写操作的binlog",从库取到binlog在本地原样执行(随机写),来保证主从数据逻辑上一致
(3)由于是需要顺序执行,所以查询语句导致的锁表就会堵塞住写入操作,进而使整体的主从延时严重
(水落石出)
四、反思
其实当时解决这个问题后就没去细想了,后来跟其他人讲起这个事情,详细深入的探讨,发现逻辑不太通,被问得哑口无言,所以才有后面的刨根问底,挺感慨的,表面上好像懂了,其实并不完全懂。后面要避免这种情况。