暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

百密难免一疏

白鳝的洞穴 2020-07-03
1036
做DBA要严谨,要严密。不过做事情难免会犯错误,百密难免一疏。这是一个比较新的案例,一个金融客户,由于一项新的和大数据应用有关的新业务,需要在核心交易的一张日志表上针对交易时间戳进行分析,每隔数秒钟采集最新的交易进行相关分析。由于时间戳平时很少使用,因此这张表上在时间戳字段并无索引,需要增加一个索引。
在核心交易相关的表上建索引是需要十分谨慎的,于是广泛征求了一些专家的意见。大家提了不少好的建议,包括分析了和时间戳相关的SQL,开发商也对核心交易进行了分析,确认肯定没有任何核心交易会用时间戳作为查询条件。另外对于ONLINE CREATE INDEX的风险,操作的时段,创建索引后的校验等等等等,列了十多项注意事项。甚至包括创建索引的时机都做了仔细的考虑,因为这张表是一张季度分区表,因此如果7月初执行这个操作是最佳时机,不过要避免7月1日凌晨操作,不要给党的生日添堵等等等等。
如此精细的考虑,按理说就应该没事了。7月1号晚上,当我都已经忘记这件事了,突然接到客户的电话,说今晚创建索引失败了。刚刚建好索引不到2分钟,业务就出现报警,核心业务中的某个查单业务就出现了延时告警,平时几百毫秒的应用响应变成了几秒甚至几十秒。同时作为只读业务的ADG节点的CPU使用率也从平时的70%多飙升到100%。于是按照应急预案,立即删除了这个索引,系统恢复正常。
查看出问题的SQL的执行计划:

查询一个月的数据时,逻辑读高达2365万,执行时间接近6分钟。从执行计划上看,该SQL使用了新建的XXXX_IDX3,而没有使用效果更好的XXXX_IDX2

经过分析发现,表上原有索引XXXX_IDX2(账号,日期) ,为了新业务应用,新建了第三个索引 XXXX_IDX3(日期,时间戳)(原计划创建一个时间戳的索引,后来在测试中发现加上日期后应用效果更好,于是对原计划做了微调,实际上在很多实施中,微调往往也是引起问题的重要因素)。检查了DBA_PART_COL_HISTOGRAMS中的和索引相关的字段的统计数据:

列名

LOW  VALUE

HIGH  VALUE

独立值数量

说明

账号

00000000019011

9981000000000046719001

11778048

201903分区相同

日期

20200701

20201001

91

时间戳

1554048002404647

1561900323544575

126771200

201903分区相同

经分

出现问题的SQL是首先从另外一张表中获得数据,然后根据“账号”这张表关联,同时在这张表中以“日期”为条件进行数据过滤。在ORDER BY里面有账号,日期和时间戳。按一般情况分析,同时具有账号日期的XXXX_IDX2是更优的选择,为什么ORACLE CBO会选择错误的索引呢?在生产环境的SNAPSHOT测试环境中,我们对此进行了模拟,并通过EVENT 10053跟踪CBO的决策算法。通过10053 TRACE,我们发现一个问题:

其中的IDX4是模拟实际生产环境的IDX3创建的索引。CBO计算该索引成本远低于其他索引,其COST是其他索引的85万分之一。这是十分不正常的。在TRACE里查找索引的相关属性:

原来这个索引没有分析,对于表上有统计数据,索引没有分析的情况,CBO会使用缺省值,LB为25来评估成本。和其他索引LB为60多万相比,无论如何,这个索引的成本都是最低的。因此只要其他索引和这个索引有共有字段,那么在CBO评估中,就肯定会落下风。这也是大量SQL采用了错误执行计划的原因。为什么这个索引会没有分析呢?按理说新建索引都会自动进行统计的。经过讨论发现,原来这张表的统计信息被锁定了。由于这是一张季度分区表,因此有些SQL可能会在季度初的第一天执行计划存在问题,于是在去年就锁定了统计信息。因此新建索引就没有分析了。

在测试环境中解除表的统计分析限定,然后对该索引进行了分析。分析后有问题的执行计划均恢复正常。从10053 trace中也可以看到,索引的状态也正确了:

实际上这个案例十分典型,也可以总结出相当多的经验。对于锁定统计信息,分区表在第一天的一些SQL的执行计划异常问题等,都是十分值得深入讨论的。今天我们的讨论主题是百密难免一疏忽,所以这些题外话我们找时间再聊。最后我们总结一下在百密中如何避免这一疏。

对于这种核心类的交易系统,是十分敏感的,因此哪怕是增加一个索引都需要做严格的评估,否则出现的后果可能是企业无法承受的。这个项目的前期工作做的很好,在大家看来是十分小的一件事都广泛征求了各方面专家的建议。不过在后面的一些小的变更上,比如增加日期字段,并没有再重新做评估。这也是我们最容易疏忽的,每个变更都被认为是小变更,无关大局,实际上这种疏忽十分致命。另外在分析的全面性方面,也缺乏经验,通过这个案例,对于表上添加索引,应该增加查询该表统计数据是否锁定的检查。同时,建完索引后应该立即检查索引的统计数据是否正常,否则很容易出问题。这次是因为客户的监控比较完善,不用检查索引统计信息是否正常,业务就已经报警了。

文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论