一个索引热块的性能问题

某个核心应用,开发反馈业务高峰期的时候,有三张表的INSERT插入操作会出现用时较长的情况,通过日志定位,认为就是数据库操作的问题。


应用的数据库架构是3节点RAC,版本11.2.0.4,连接池使用的tns配置是failover,默认连接节点1。


高峰期AWR的数据库负载情况如下,

640?wx_fmt=png


640?wx_fmt=png


高峰期AWR等待事件中的Top 10,可以看出来,索引争用、行锁争用,以及热块等待,占比比较高,其中行锁争用,由于应用逻辑中,存在对同行数据的并发访问,有特殊的处理,所以暂时关注另两个问题,

640?wx_fmt=png

P.S. 关于Top,有个小知识点:《AWR Top 5和Top 10的演进》。


根据热块所在的段信息,能定位到开发提到的三张表中,三个主键索引,以及一个非唯一索引段是争用的热点,因此推测,热块争用和索引争用,是同一个问题,都是因为索引块成为热点所产生的,如何解决索引热点的问题,就成为了关键,

640?wx_fmt=png


这三个主键索引,都是采用序列值填充的,因此每次向表中插入一行数据都会向索引最右侧的索引块插入新值,即发生索引单向增长,当数据库没有空间的时候,就会发生9-1分裂,创建新的索引块,尤其是高并发的系统,随着高峰期请求量的增加,越容易让索引叶子节点最右侧的数据块成为热点,产生争用。


由点及面了解Oracle的Sequence序列》介绍了针对序列作为主键或者唯一键产生性能问题的解决方案,

方案一:将索引重建为reverse-key index

这种方案,可以缓解索引热块的争用,但是随着数据量的增加,索引越大,对于范围检索,一次检索可能需要读取到buffer cache的索引数据块就会越多,一方面可能会产生磁盘IO方面的等待,另一方面可能会将其他表或索引的数据挤出内存,因此,很有可能只是从索引争用,转换成另一种资源的等待,没有从根本解决这个问题。


方案二:将索引重建为hash partition index

如果是单实例,这种方案会有效,因为他将原先争用的块数据,分散到了不同的数据块,但是,如果迁移RAC,由于频繁的使用,可能会出现索引数据块在节点间频繁的传输,而且随着节点数增加,传输的可能性就会越大,还是会产生性能的问题。


方案三:编码生成的智能主键

根据实例号、进程号、以及序列值,拼接出能避免实例间传输、避免索引单向的争用、以及保证唯一的主键值。


我们采用的是方案二,将主键索引,改为16个分区的hash分区索引,由于有停机时间,因此指定并行度,加快执行速度,4000万记录的表,大约50秒能完成,

create index idx_t_01 on t (id) globalpartition by hash (id)partitions 16 tablespace IDX_TBSparallel 16;index idx_t_01 on t (idglobal
partition by hash (id)
partitions 16 tablespace IDX_TBS
parallel 16;


调整之后,高峰期,相应的争用,明显降低了,热块段信息中,之前出现的三个主键索引和一个非唯一索引,不再出现,从应用端看,超时的现象,有所缓解,

640?wx_fmt=png


但是,方案二说了,如果是单实例,这种方法有效,如果改为RAC,则可能出现索引数据块在节点间频繁传输的场景,影响性能,由于应用采用failover连接方式,正常都在一个节点连接,但是不排除故障场景下,部分连接选择其他节点的可能,此时,对于这种hash分区索引就存在索引数据块在不同节点间传输,算是一个隐患。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读