一个案例读懂ORACLE ASSM机制--技术人生系列第五十七期--我和数据中心的故事
Posted 中亦安图
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个案例读懂ORACLE ASSM机制--技术人生系列第五十七期--我和数据中心的故事相关的知识,希望对你有一定的参考价值。
前言
ASSM机制是oracle在段内进行空间自动管理的机制;通常来说,这个机制能很好的帮我们查找、定位、分配相关的段空间;然而,所有的机制都不是那么完美的,在具体的CASE中,我们需要充分理解它,才能更好的掌控它;今天的CASE分享,希望大家能对ASSM机制有真正充分的理解。
1
问题来了
“我们这一个奇怪的问题吧,一个简单的insert语句居然执行了上百秒。”
在一个投产上线后的某一天,负责应用维护的同事描述了他的疑惑;
很快,他展示了应用日志中关于那条insert语句超时的相关信息;很简单的语句,在应用日志中打出了整个SQL文本:
INSERTINTO XXXX_CER(XXXX_CER_ID,XXX_NO,U_ID,XXXX_CER,XXX_CER)
VALUES(RA_SEQUENCE.nextval,:1,:2,:3,:4);
执行时间超过了100S;
“这个语句看起来确实很简单,当天一直在报超时吗?”
“并没有,正常执行都挺快的,当天只是出现了极个别的几条而已,后来好像就没再报了,当时数据库是不是出了什么问题?”
“看起来是有些奇怪,但是具体原因还需要细查;”
2
定义问题
当这样一条SQL摆在你面前,它执行花费了超过100s,你会考虑到造成这一现象的可能因素都有哪些呢?
INSERTINTO XXXX_CER(XXXX_CER_ID,XXX_NO,U_ID,XXXX_CER,XXX_CER)
VALUES(RA_SEQUENCE.nextval,:1,:2,:3,:4);
既然是极个别的出现执行缓慢的情况,那么应该首先应该排除数据库整体性能缓慢导致SQL执行慢的情况;我们很简单的收集一个包含问题时段的AWR报告来看,数据库整体DB Time并不高,也未出现异常的等待事件;
看来还是要针对单个SQL来进行分析;
于是我们在数据库中找到该SQL的sql_id,查看其历史执行情况如下:
可以看到,在问题时段内执行的次数并不多,但是其对应的逻辑读和物理读大大地超过了正常时段,这样执行时间长也就理所当然了;
现在,我们就可以把问题精确定义为:“一个insert语句为什么会在某一时间点产生大量的逻辑读(和物理读)?”
3
追踪现象
有了sql_id(22xzq114gz65j),有了大致的时间段,我们就可以追踪这个语句具体执行过程了;我们来查看数据库活动会话历史中关于该SQL的执行情况:
可以看到,对于单条SQL某一次执行,在活动会话历史的视图中,被采样的次数竟然达到了139次;进一步追踪这条SQL单次执行过程中(指定sql_exec_id)产生的等待:
可以看到,在执行过程中主要出现的等待事件是数据文件的顺序读;而且访问的对象都是XXXX_CER表(对象号为15642);
4
“合理”推断
看到这些,我们停下来思考看看刚刚重新定义的问题:“一个insert语句为什么会在某一时间点产生大量的逻辑读(物理读)?”从等待事件的情况来看,这个会话一直在读插入目标对象(表),看来并不是在维护表的索引,那它为什么要不断的读这个表里不同的数据块呢?
我们不妨先dump在insert过程中不断查找的几个块来看看,这些数据块有什么共同的特征,选取典型的数据块信息如下:
特征:
1.该数据块中存在3条记录;
2.单条记录的长度似乎偏长,每条记录的第3列和第4列的长度达到了1100个字节左右;
看起来这个表似乎还有点特殊,再看一下表的定义:
看到了两个字段的定义长度为4000,似乎一下就找到了一个方向;
试想一下,一个数据块的大小是8192字节,这里的如果插入数据的长度不再是2000字节左右的大小,而是偶然的插入更长的数据,一时间需要找到足够存放该记录的数据块可能需要查找更多的块;
再仔细看看上面块的信息:
可以看到,这个块中剩余空间(avsp available space)大小为0x5f3(十进制1523),也就是说,如果插入的数据记录占用空间大于1523,那么必然无法存放在这个块里,这个块不合适,那么ORACLE将继续寻找下一个合适的块,如果再找到不合适的,继续找,如此反复,那么找的块就多了,对于数据文件的单块物理读也就多了;
感觉好像很合理,不如先与应用维护人员确认插入失败的那条记录是否特别长;
然而,随后应用维护人员给出的答复却出乎我们意料:
“插入失败的记录更短,一般来说列3和列4的列值是同样的数据,长度都是1100字节左右,单条记录的总长度在2200字节左右,而插入失败的记录则是只有列3有数据,而列4则为空值,也就是说插入失败的记录总长度应该在1100字节左右!”
看似合理的的推断,好像又没有得到证据支持,再次陷入沉思;
5
深入思考
再仔细回过头来思考,大的方向应该没有错,只是思路并没有特别清晰;我们重新捋一下过程,再来看看分析过程中的几个重点:
1.通常情况下,插入的记录长度在2200字节,而在插入2200字节的记录时并没有像插入更短长度记录时需要查找那么多块,为什么需要空间更小反而需要查找更多的块?
2.对于找到的剩余空间还有1523字节的块,为何在插入大约1100左右字节的记录时,仍然无法将数据插入到这个数据块中呢?
再将问题转换一下:
1.ORACLE在插入数据时,是如何查找到“合适剩余空间”的块的?
2.ORACLE在查找到“合适剩余空间”的块时,是如何判定能否真的能插入到该块中呢?
把上面两个问题想清楚了,这里的问题似乎也就应该明了了。
6
理解ASSM
要想想清楚上面两个问题,需要先理解ORACLE的ASSM机制;
在ASSM机制中,存在一个位图的概念,它是一个二进制的数组,能够迅速有效地管理存储扩展和剩余区块(free block),每个块有多少剩余空间根据位图的状态来确定,其标志位的状态包括包括unformatted,0-25% free, 25-50% free, 50-75% free, 75-100% free和FULL;
另外需要注意的一点是,ASSM中还有一个PCTFREE的概念,该值为保留空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert了,只能被用于update;即:当使用一个block时,在达到pctfree之前,该block是一直可以被插入的;
理解了上面的ASSM机制,我们可以很清楚的回答上面的两个问题了:
1.ORACLE在插入数据时,是如何查找到合适剩余空间的块的?
答:通过ASSM的位图信息来查找到合适的剩余空间;对于8192的数据块,如果需要插入长度为2200字节的数据记录,那么ORACLE需要寻找25-50% free及以上的数据块;而如果插入的是1100左右字节的数据记录,那么只需要寻找0-25%free及以上的数据块即可;
2.ORACLE在查找到合适剩余空间的块时,是如何判定能否真的插入到该块中呢?
答:以本案例为例,需要插入1100左右字节的数据记录,查找到0-25% free的数据块,比如前面dump的剩余空间为1523字节的块就是这样的数据块;但是实际上,还需要考虑保留10%也就是819(也就是8192*10%,PCTFREE部分)的空间,那么该块真实可以插入的数据记录的最长长度应该在1523-819=704字节左右;当然也就无法插入1100字节的数据记录;
7
逻辑推演
依据上面两个问题的回答,我们可以理解这样一种情况:
1)在大多数情况下, 我们插入记录长度为2200字节记录时,总体来说,段中单个数据块基本保存3条记录;
2)当一个数据块中存在三条记录后,块空间的剩余大小大约在8192-2200*3=1592字节左右;
3) 剩余1592字节左右的块,在位图中会被标记为0-25%free;
4) 在不断继续插入2200字节的记录时,因为2200字节超过了8192的25%,显然ORACLE不会试图去使用0-25%free的数据块,而是会使用更高free的数据块或者开辟新的数据块;
5)于是,段中存在大量0-25%free的数据块,实际上这些块的剩余空间约在1600字节左右;
6)当需要插入一条长度为1100字节的记录时,ORACLE认为0-25% free的块是适合存放这些记录的,然而实际上最终因为实际剩余空间的大小和PCTFREE的原因,这些块并不能存放下这条记录,于是继续寻找这类数据块;
上面的过程,基本就能描述insert过程出现大量数据文件顺序读等待事件的情况;
那么,照上面的逻辑,我们会问,现在我们只要插入长度为1100字节的记录,就还会需要长时间的找合适的数据块,长时间的出现数据文件的顺序读等待吗?答案是否定的!因为,在寻找到一个0-25% free的数据块而无法将数据插入到该块之后,ORACLE就会将块的位图信息更新为full状态(尽管块中可用空间还有1500字节),后续插入记录就不会再来试图使用该数据块,即不再出现执行缓慢的情况;也就是说,上述情况出现过一次之后,大量的块会被置为full状态;所以这种情况不会出现的非常频繁;
所以,我们遇到的问题的本质就是:ASSM的位图信息只有极少的几种状态信息来标记数据块的剩余空间,不够精准,在极端情况下可能会导致insert/update操作过程中试图去使用并不合适的数据块,导致了大量的数据块读取操作!
8
场景重现
理解了前面的过程之后,其实我们就可以轻易的模拟出上述情况:
1.创建一个表,默认PCTFREE为10
2.插入15条记录,每条记录占空间大小为2200左右;
3.查看当前数据占用的extents数
当前为数据段分配了一个extent,占用8个block空间;文件号4,块号为123904-123911总共8个块。
4.查看当前段的位图信息
可以看到,8个block中,除了3个是元数据block外,其他五个数据块位图信息都显示0-25% free,事实上通过前面的分析,我们也能知道这里每个块中存放了3条记录;
5.准备插入一条1100字节的记录
6.通过10046 event跟踪
在会话级设置10046事件进行跟踪,然后执行刚刚准备的insert操作;
可以看到,简单的insert语句,用单块读的方式遍历了整个表的所有块(等待事件中p2包括了123904-123911);
7.查看当前表占用的extents数
在新插入一条记录时,原有的extent不能存放这条记录,新扩展了一个extent;
8.查看当前的位图信息
在新插入记录后,原0-25% free的块位图信息被更新为full状态;
至此,整个问题的现象已经被完全重现出来,而且理论依据也非常充分了。
9
我们能做什么
首先,我们需要理解,触发上述问题必须要有几个特点:
通常插入的记录长度偏长(25%的块空间不够存放一条记录);
偶尔插入的记录长度相对于以往偏短(记录的长度低于块大小的25%)
在出现一次上述情况的过程,同时也是“修正”位图信息的过程;
综合来看,触发条件较为特殊,因为有自动修正的过程,触发次数不会太多;
事实上,理解了上述整个过程之后,我们会发现,面对这样的情况,其实可以做的并不多;我们可以做的几点包括:
1.如果可以,在表定义上给字段定义合理的default值,避免出现记录长度大幅变化的情况;
2.如果上述情况出现频繁,可以考虑调整数据库的相关隐含参数,指定ORACLE寻找空块的个数(两个隐含参数大家可以了解下:_assm_high_gsp_threshold和_assm_low_gsp_threshold);
10
总结
分析重现完整个问题,我们能说oracle ASSM机制是存在大问题的吗?其实也不能,从设计上来看,ASSM机制是为了通过有限甚至极少的数据来定位数据块的使用情况,在节省空间的情况下可能会出现极端情况下的性能异常,在设计上这只是一个平衡;如前面的建议,设置隐含参数(_assm_high_gsp_threshold和_assm_low_gsp_threshold),对于这个问题而言可能会有效,但是同样又有可能造成大表/索引出现较严重的空间浪费的情况;所以,对于问题的处理,我们需要在理解原理的基础上结合具体的CASE,分析解决方案的利弊,选择一个我们可以接受的方案。
如果读完您有所收获,不如一起转发分享,您的转发是我们持续分享的动力!
招聘啦:中亦科技北京/上海/广州/济南都在招中级和高级oracle dba,有志同道合的朋友或者身边有合适的朋友请帮忙推荐,简历请发51994106@qq.com。
更多内容请关注——中亦课堂
中亦课堂,带你从容进步
往期经典回顾
回复“039”第三十九期:技术人生系列·我和数据中心的故事(第三十九期)-温馨提示:数据库升级到11G/12C的潜在风险提示
回复“040”第四十期:技术人生系列·我和数据中心的故事(第四十期)-一次巧妙的SQL优化
回复“041”第四十一期:技术人生系列·我和数据中心的故事(第四十一期)-风险提示--这么用X86,小心ORACLE+RAC中招
回复“042”第四十二期:技术人生系列·我和数据中心的故事(第四十二期)-风险提示--风险提示:修改参数一定要确保重启后仍然生效!!
回复“043”第四十三期:技术人生系列·我和数据中心的故事(第四十三期)--这个锅,我们运维,不背! 开发和运维都该看看
回复“044”第四十四期:技术人生系列·我和数据中心的故事(第四十四期)--数据库高手带你从“山穷水尽”到“柳暗花明”
回复“045”第四十五期:技术人生系列·我和数据中心的故事(第四十五期)--看高手如何用机器学习来分析解决数据库的疑难故障
回复“046”第四十六期:技术人生系列·我和数据中心的故事(第四十六期)--风险提示:操作系统动态增加CPU带来的数据库重启风险
回复“047”第四十七期:技术人生系列·我和数据中心的故事(第四十七期)--从一次性能压力测试达不到TPS的优化案例看应用设计的重要性
回复“048”第四十八期:技术人生系列·我和数据中心的故事(第四十八期)--X86比小型机要慢很多?性能优化专家帮你来翻案!
回复“049”第四十九期:技术人生系列·我和数据中心的故事(第四十九期)--从案例看一个好 的DBA为什么这么值钱
回复“050”第五十期:技术人生系列·我和数据中心的故事(第五十期)--生产比测试慢?从一个案例思考应用程序行为与服务器配置之间的性能关系
回复“051”第五十一期:技术人生系列·我和数据中心的故事(第五十一期)--从一个常见ORA错误的分析过程看工程师的必备技能
回复“052”第五十二期:技术人生系列·我和数据中心的故事(第五十二期)--数据库大版本升级27个约束消失之谜
回复“053”第五十三期:技术人生系列·我和数据中心的故事(第五十三期)--发现隐患,就在上线前
回复“054”第五十四期:技术人生系列·我和数据中心的故事(第五十四期)--不惧bug!一个oracle bug的分析和规避
回复“055”第五十五期:技术人生系列·我和数据中心的故事(第五十五期)--这不仅仅是SQL优化!
回复“056”第五十六期:技术人生系列·我和数据中心的故事(第五十六期)--ORACLE问题分析过程中的“暴力美学”
以上是关于一个案例读懂ORACLE ASSM机制--技术人生系列第五十七期--我和数据中心的故事的主要内容,如果未能解决你的问题,请参考以下文章