从一次性能压力测试达不到TPS的优化案例看应用设计的重要性--技术人生系列第四十七期-我和数据中心的故事
Posted 中亦安图
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从一次性能压力测试达不到TPS的优化案例看应用设计的重要性--技术人生系列第四十七期-我和数据中心的故事相关的知识,希望对你有一定的参考价值。
案例分享和风险提示预告
上线前的压力测试,是系统上线过程中重要一环;
一轮好的压力测试,不仅能发现系统配置方面的不足,更重要的是能发现应用设计上的缺陷;压测时发现问题之时,事实上也是我们结合应用逻辑提出有效解决方案的大好机会;这个时候的改动,代价更小、调整更方便,而且还能直接看到压力环境下的测试效果;也就能验证你提出的解决方案是否有效了。
今天笔者要跟大家分享的问题,是一个压测过程中与"enq: TX - allocate ITL entry"等待事件有关的CASE;这类等待事件出现的正是与应用处理逻辑紧密相关;在处理过程中,还需要结合数据库的原理来分析;
Oracle数据库问题,还是找不到原因?
不妨找中亦科技试试,我们将尽最大努力为您找到导致故障和性能问题的根本原因。
问题来了
01
某客户,压力测试正在进行中,在高压环境下,系统的性能表现并不好;在数据库中,我们可以看到出现了各种在高压环境下会出现的等待事件:
客户对此提出,"enq:TX - allocate ITL entry"等待事件是否可以通过什么方式消除,目前分析看来,正是这个等待事件导致整个测试的压力上不去。
切记草率处理
02
科普一下
1)什么时候会出现等待事件enq: TX - allocate ITL entry呢?
在数据库进行DML操作修改一个数据块时,通常会在数据块的头部占用一个事务槽,存放该DML操作的相关事务信息,如果DML操作无法获取某个块上的事务槽,就会出现这个等待事件;
2)对于该等待事件常见的解决方案是什么呢?
Ø 在数据块上保留足够空间留给事务槽
n 保留足够的pctfree
n 初始化足够大的inittrans
Ø 降低同一个块上出现过多事务的可能性
n 加快事务的完成,避免出现长时间未提交的事务
n 减少数据块上的数据量,避免在同一个块上出现过多事务
n 结合业务,离散同一数据块上的数据,避免在同一个块上出现过多事务
关注源头
1) 是哪个语句哪个对象上产生了这个等待事件
出现了异常等待事件,我们需要定位是导致等待事件的直接原因;
可以清楚的看到,导致问题的主要语句是g52nu1qdyvq46 ,等待涉及的对象是74140;
SQL内容如下:
等待的对象:
看起来,等待涉及的对象是一个索引;
2) 索引的列值是什么
从业务逻辑看,MSGSNO是一个业务的流水号,是一串单向增长的数据,而第二列DLFADM列则是一个机构代码,目前业务情况下基本就是同一值;
查询数据得到的结果类似如下:
对于这样的数据,如果高并发的事务出现,则极有可能出现流水号接近,生成的索引数据集中到某一个数据块中,导致单个块上的事务槽被占满的情况;
3) 对象的大小有多大
再查看索引对象的大小,为856MB
常规方案来解决----第一次头脑风暴
面对这种在索引块上的事务热点竞争,结合我们上面说的原理,其实会有很多解决方案;针对这一具体案例,我们可以考虑下面的几种方案:
1. 在确认该索引不会被范围扫描时使用,将索引改造为hash分区索引, 避免热点数据;
2. 在确认该索引不会被范围扫描时使用,将索引改造为反向索引,避免热点数据;
3. 保留更大的事务槽空间;
对于这一CASE,项目组试着多管齐下,来解决该问题:
再次测试效果不佳—我们遗漏了什么
重新测试,我们发现,问题并没有得到缓解,按照原理来说,上面做的看起来已经足够多了,但是为什么解决不了问题呢?看起来,似乎这里头还存在一些特殊之处,我们需要重新捋一遍,才能找到问题的根本原因。
别着急,多思考个三五分钟,问题原因就在后面,什么时候往下翻,由你决定…
根因分析过程
03
从头来过
我们再从头来查出现等待事件的详细信息:
出现问题的依旧还是同样的SQL,只不过,这一次我们分析到该等待事件都集中到了该索引的同一个数据块上(注意:这里索引被重建,所以current_obj#发生了变化);
按理说,业务数据在持续的插入,那么热点的MSGSNO是在不断变化的,经过我们hash/reserve之后,热点的数据块应该也是在不断变化的;可是为什么到了这里,热点块为什么始终落在一个数据块上呢?难道业务这么巧?还是其他的什么原因?
别着急,多思考个三五分钟,问题原因就在后面,什么时候往下翻,由你决定…
看看他的特殊之处
很多同学看到这,肯定第一个想到的是该块是否为与段空间管理相关的位图块;我们可以很快的查询到:
该块为索引分区SYS_P1576第一个extent中的数据块;
很显然,该分区只有少数几个extent,每个extent的大小也都不大;segment的位图块通常是在第0个extent中,这个块存在与extent 1中,也就不是该索引分区的位图块;
数据块分析
分析一个数据块,我们可以将数据块直接DUMP出来;SQL> alter system dump datafile 48 block4173106;
得到的trace文件内容如下:
首先从内容上看,确实存放的就是索引数据的内容;事务槽从0x01到0xa9全部用完,十六进制A9换算为十进制,正好169个。
可以看出上面的数据块中,1个默认事务槽是C代表已经提交,剩下的168个事务槽都是Active Transaction状态;
接着看行记录,通过数据记录来分析热块的形成原因;
回顾我们所建立的索引,是由两个列组合而成;
DLFADM代表法人代码,默认都是本银行,基本为0000。
而这里的数据,可以看到:
col0 全是null;
col1为4个30,这里30正是“0”的16进制ASCII码;
col2则显然存放的是对应数据的rowid信息;
那么这里的疑点来了,这里col0,也就是表中的MSGSNO为什么会全部都是null呢?
猜想与验证
按照业务逻辑,似乎这里的MSGSNO列不应该为null值,当我们dump出来的数据跟我们预期的数据不一致的时候,我们不妨直接到表中去查询真实数据:
看来,表中的数据完全没有MSGSNO为null值的情况;那么,为什么dump出来的都是null数据呢?我们不得不怀疑:
要排除上面两个可能的bug看起来很难,我们就需要换个思路去想了;
但是我们要结合实际情况来分析;我们假设一开始插入进来的数据确实是null,那么即使经过hash/reserve,这些数据还是会集中存储到某一个索引块中;我们在数据表中无法查找到该列值为null的情况,恰恰是因为它还没有提交,而它在提交时又将该列数据修改为非空的一个序列值;
上述的假设看起来天衣无缝,不妨与开发进一步确认。
真相大白
04
经过与开发人员沟通,了解到这部分的操作确实如上所述,其业务逻辑伪代码类似如下:
业务这样做是因为,需要在业务处理过程中经过一系列操作后,才能获取到MSGSNO的真实值,在此之前,需要先将表的数据插入到XXXVJX表中,插入时先用null值代入,后续再将MSGSNO值更新过来;
这样,业务逻辑的设计似乎是造成这个问题的根本原因;
解决方案
05
理解了问题的原因,要给出对应的解决方案也就不难了;我们同样给出解决方案,在不改变业务逻辑的前提下,我们先使用一个sequence生成一个非空值进行插入,这样就能避免null值插入时,无法通过hash/reserve方式将数据打散的情况;
通过上述调整,我们再次进行压力测试,该类SQL引起的ITL事务槽的问题就已经得到圆满解决。
中亦学院公开课已经开播两集了,为了方便大家回顾我们的精彩课程,我们特别录制了前两集的公开课视频,链接如下,欢迎下载分享:
第一集:ORACLERAC性能调优案例分析
链接:https://pan.baidu.com/share/init?surl=nuHejdZ 密码:0d3e
第二集:SQL优化必须过的三关
链接:http://pan.baidu.com/s/1nvxceF3 密码:8tdy
第三集:理解进入oracle世界的入口--等待事件
链接:https://pan.baidu.com/s/1hsEN8XY 密码:lxwg
数据库服务,就找中亦科技!
往期经典回顾
回复“034”第三十四期:技术人生系列·我和数据中心的故事(第三十四期)-一个CASE看ORACLE新特性的本质
回复“035”第三十五期:技术人生系列·我和数据中心的故事(第三十五期)-从天而降的TRACE
回复“036”第三十六期:技术人生系列·我和数据中心的故事(第三十六期)-颠覆传统调优方法的案例分享
回复“037”第三十七期:技术人生系列·我和数据中心的故事(第三十七期)-一个案例看Oracle的历史故障回放功能是如何碾压其他数据库的
回复“038”第三十八期:技术人生系列·我和数据中心的故事(第三十八期)-从truncate慢感受12c新特性的痛
回复“039”第三十九期:技术人生系列·我和数据中心的故事(第三十九期)-温馨提示:数据库升级到11G/12C的潜在风险提示
回复“040”第四十期:技术人生系列·我和数据中心的故事(第四十期)-一次巧妙的SQL优化
回复“041”第四十一期:技术人生系列·我和数据中心的故事(第四十一期)-风险提示--这么用X86,小心ORACLE+RAC中招
回复“042”第四十二期:技术人生系列·我和数据中心的故事(第四十二期)-风险提示--风险提示:修改参数一定要确保重启后仍然生效!!
回复“043”第四十三期:技术人生系列·我和数据中心的故事(第四十三期)--这个锅,我们运维,不背! 开发和运维都该看看
回复“044”第四十四期:技术人生系列·我和数据中心的故事(第四十四期)--数据库高手带你从“山穷水尽”到“柳暗花明”
回复“045”第四十五期:技术人生系列·我和数据中心的故事(第四十五期)--看高手如何用机器学习来分析解决数据库的疑难故障
回复“046”第四十六期:技术人生系列·我和数据中心的故事(第四十六期)--风险提示:操作系统动态增加CPU带来的数据库重启风险
以上是关于从一次性能压力测试达不到TPS的优化案例看应用设计的重要性--技术人生系列第四十七期-我和数据中心的故事的主要内容,如果未能解决你的问题,请参考以下文章