在一个风和日丽的下午,xxx 忽然接到业务方线上业务数据库CPU资源告警信息,立马放下手里的枸杞登录业务方阿里云控制台查看具体问题。
对于数据库以后正在产生中的问题,咱们首先从数据库实时会话信息中尝试抓取无效信息,能够看到该告警实例的会话曾经呈现沉积状态,大量会话处于"Sending data"状态且从TIME字段能够看到这些会话长时间执行未完结。会话长时间执行示意以后会话始终占用的数据库资源未开释,且沉积会话根本为同一类型的业务SQL,这也就是导致咱们数据库资源打高的问题SQL。
咱们拎出这个问题SQL登录数据库查看SQL的执行打算,对问题SQL进行剖析,从SQL执行打算中咱们很显著发现一个资源耗费比拟大的操作"ALL"全表扫描操作,而且比拟诡异的一点是,a表进行表关联possible_keys明明是primary然而却没有应用,所以咱们下一步的方向就是排查为什么表关联没有无效利用索引。
导致索引生效的问题的起因最常见的就是隐式转换,对于隐式转换咱们之前的文章也做过比拟具体的解说,总体概括次要是以下几个场景:
1)传递数据类型和字段类型不统一2)关联字段类型不统一3)关联字段字符集不统一4)校验规定不统一
在表关联字段索引生效的状况下,可能导致索引生效的场景次要是2~4,于是咱们马上查看表关联字段相干信息进行一一验证。
emmmm,查问到的后果却仿佛有些不尽人意,表关联字段均是bigint类型,完满的躲避掉了以上所有可能。
再次陷入深思,在没有产生隐式转换的状况下索引个别都是会无效利用的,除非MySQL优化器认为ALL全表扫描的效率并不差。咱们晓得,MySQL优化器会通过具体表的统计信息基于CBO进行代价计算,帮咱们抉择最佳执行打算。然而统计信息并不是齐全准确的,某些时候可能会呈现肯定的误差,也正是因为统计信息的误差,就可能导致MySQL优化器谬误的抉择一个并不是很好的"最佳执行打算"。接下来咱们就能够进一步查看表的统计信息以及hint进行验证。
表关联对应的统计信息
通过hint强制走primary索引察看执行打算、并测试执行效率
问题排查到这里,导致该SQL大量耗费CPU资源的起因也就上不着天;下不着地了。对于业务方目前的CPU打高的状况,咱们能够倡议业务方先将目前沉积的会话进行Kill,防止影响其余失常的业务查问,等数据库CPU资源有所回落后,在数据库执行"analyze table"对问题表的统计信息从新采集,统计信息更新后MySQL优化器就能够正确的抉择最佳执行打算。
统计信息更新:
执行打算更新:
尽管客户的问题曾经解决,对于本案例还是有一些点值得咱们思考:
索引生效的场景都有哪些?
- 隐式转换
- 统计信息不精确
MySQL统计信息是如何更新采集?
在MySQL中有一些参数设置决定了统计信息采集的行为形式,个别状况下不会做特地设置,咱们须要正确的了解这些参数,明确统计信息只是一个统计估计值,并不是相对精准。
- 统计信息相干参数
innodb_stats_method 默认nulls_equal,示意统计信息时把所有的null当作等值看待
innodb_stats_auto_recalc 是否关上自动化采集统计数据 ,默认关上,当表数据量更新10%触发从新采集统计信息
innodb_stats_on_metadata 默认敞开,若该参数开启时示意数据库执行"show table status",拜访"INFORMATION_SCHEMA.TABLES or
INFORMATION_SCHEMA.STATISTICS"时,都会触发从新采集统计信息的操作
innodb_stats_persistent 统计信息是否长久化到磁盘,默认关上。长久化磁盘当数据库重新启动后可从磁盘读取。
innodb_stats_persistent_sample_pages 默认20,对于长久化存储统计信息的表,每次从新采集信息须要采集20个索引页进行剖析
innodb_stats_transient_sample_pages 默认8,对于非长久化的表,其统计信息从新采集须要扫描8个索引页进行剖析
- MySQL几种从新采集统计信息的机会
新关上一张表时
表数据变更超过10%触发该表的统计信息从新采集
当innodb_stats_on_metadata参数关上,数据库执行"show table status",拜访"INFORMATION_SCHEMA.TABLES or INFORMATION_SCHEMA.STATISTICS"时
手动执行analyze tables时
对于analyze table操作
执行该操作须要具备该表的select/insert权限
反对Innodb、Myisam、NDB存储引擎下的表,不反对视图
反对对分区表中某个分区独自执行统计分析:alter table ... analyze partition
在执行analyze期间,会对该表加一个读锁。
在我探寻了技术的真谛后,我又默默的端起了已经放下的枸杞。