问题现象:
开发报告查询语句突然变慢。
处理过程:
1、在从库查看执行计划:
并且执行查询,结果是返回159条数据,只需要0.58秒,并不慢
2、了解到原来应用连接的是主库,随即上主库查看执行计划,如下,可以看到执行计划是不一样的,从库性能没问题,而主库性能有问题,初步可以断定,就是统计信息不准确的原因。于是让开发先将连接修改到从库,问题得到解决,接着继续分折统计信息不正确的原因。
原因分析:
(1)语句很简单,只是对一个表做查询,所以对表做分析,更新统计信息,对表做分析之后,发现统计信息仍然没有变化,记录数显示仍然是7千多万条。
(2)通过select count(1) from sy_paid_user_retained可以看到,发现表的总记录数是2千多万,这能确认就是统计信息不准确的原因,一开始认为表比较大,会不会是因为采样不准的原因,所以依次增加innodb_stats_sample_pages参数,继续上面的分析表,甚至将innodb_stats_sample_pages设置为10240,完全足够大,问题还一样存在,哪又是什么原因导致统计信息无法更新的?
(3)查看show engine innodb statusG;可以看到history list length值非常大,已经到达1亿多,这通常代表有很长的事务没有提交。
果然,存在两个超长事务,最长的一个已经运行了3613099秒,=运行了(3613099/3600/24=41天),已经运行了41天(没有监控真可怕)。
(4)kill掉上面两个大查询,然后再次执行分折表,结果一样,统计信息还是没变。以往删除长事务之后,history list length就下降,通常性能问题也得到解决,这次却不行。
(5)通过向开发了解,最近是有一个作业,执行了大量的delete操作,我们从统计信息来看,应该有5000万的delete。从库不存在长事务,所以不存在这个问题。这个history list length太长的问题,只能让系统慢慢回收。
改善措施:
1、增加长事务的监控,运行超过3000秒报警;
2、考虑自动kill 掉select 长事务;
3、讨论后,修改事务隔离级别,从rr修改为rc。