首  页  论  坛 登  录  注  册 用户中心 风  格 论坛状态  会  员 最新贴子 灌水宝贝  搜  索 短消息 博客   社区监狱 聊天室 退出
  当前位置:  论坛首页 »  Oracle技术讨论 »  DBA日记讨论区
发新贴子 回复贴子 您是本帖第 620个阅读者     浏览上一篇主题    刷新本主题   浏览下一篇主题
11101/2页12
 主题:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数 [全部贴] [楼主贴] [打印] [收藏]
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
版块置顶  锁定  置为精华  改变显示颜色 
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数

322 理解表的存储结构 3)那些逝去的老参数

有几个参数可能随着Oracle数据库版本的变化逐渐的逝去了,不过那些参数可能承载了很多老DBA的荣誉和苦泪。它们是pctusedfreelistsfreelist groups。随着自动段空间管理(ASSM)在9i的推出,现在新的数据库很少还在使用手工段空间管理(MSSM)。自动段空间管理和手工段空间管理最大的区别���于空闲块的管理上,自动段空间管理出现之前,Oracle的空闲块是通过FREELIST机制来管理的,表和索引在被创建的时候必须指定PCTFREEPCTUSEDFREELISTSFREELIST GROUPS 等参数。一个被格式化后的数据块被挂在FREELIST上,这样需要插入数据的前台进程可以在FREELIST上找到可以插入数据库的块,插入相关的数据,数据插入后,如果数据块中的空闲空间小于PCTFREE指定的比例,那么这个数据块就不能再次被插入数据了,这个数据块将从FREELIST上摘除,下次插入数据的时候,就会插入到其他的数据块中。这个数据块中如果有数据被删除后,空闲空间低于PCTUSED的指标,那么这个数据块将会再次被放到FREELIST上,这样这个数据块就可以再次插入数据了。有人可能会有疑问,一个比较“满”的数据块,如果删除了数据,那么不就马上可以被插入数据了吗?这个时候马上就放回FREELIST上不就行了,还用PCTUSED干什么呢?实际上Oracle的这个设计是十分优秀的,如果不设计PCTUSED��个参数,我们会碰到这样的情况,一个数据块刚刚插入数据后被从FREELIST中摘除,马上又因为删除数据被再次放入FREELIST,那么就可能会产生抖动,FREELIST的性能就会因为频繁重组而急剧下降。

同样的道理,在一个MSSM管理的段中,如果PCTFREEPCTUSED两个参数设置的不合理,那么这种抖动现象还将会出现。比如说我们设置PCTFREE30,设置PCTUSED65,如果行长度较大的话,如果一个数据块中刚刚插入一条记录后马上又删除了23条记录,这种情况下,这个数据块可能出现刚刚被从FREELIST上摘除,就马上被再次放入FREELIST的现象。从对MSSM管理空块的方法,我们可以看到设置合理的PCTUSED参数的重要性,如果PCTUSED参数设置过高,可能导致FREELIST的抖动,如果PCTUSED参数设置过低,可能导致数据块中存储的记录数过少,影响全表扫描操作的性能。

讨论完PCTUSED我们再来看看另外一个重要的段空间管理相关的参数FREELISTSFREELISTS是用于存放可插入数据的数据块的,FREELISTS存在于perment data segmenttemporary data segmentindex segmentrollback segment中,一个段中有几种类型的FREELISTS

l         MASTER FREELISTS

l         PROCESS FREELISTS

l         TRANSACTION FREELISTS

一个段中只有一个MASTER FREELISTS,这个FREELISTS在段创建的时候就创建了,段中的高水位以下的空闲块都挂在MASTER FREELISTS上。当某个前台进程需要插入数据的时候,就可以到MASTER FREELISTS上去查找空闲块,查找操作从FREELISTS的头部开始,直到好到可以插入数据的块为止。

明眼人看到这里马上就会看出问题来了,FREELISTS是一个串行的机构,如果有大量并发的会话需要插入数据的话,FREELISTS就会成为一个瓶颈。实际上ORACLE对此也早有对策,Oracle存在另外一种FreelistsProcess FreelistsProcess FreelistsMaster Freelists是一种主从协同机制,每个Process Freelists上链接了一组空闲块,这些空闲块是从Master Freelists上摘取的,前台进程要插入数据的时候,首先必须锁定一个Process Freelists,然后从这个Process Freelists上查找一个空闲的数据块用于插入数据。当Process FreeLists上也没有可用的空闲块的时候,会锁定Master Freelists,从中分配一组空闲块到Process Freelists上,然后再从Process Freelists上分配空闲的空间。听起来似乎很不错,OracleProcess Freelists的设计避免了Freelists成为并行插入操作的瓶颈。不过大家要注意的是,Oracle缺省的Freelists参数值是1,在Freelists参数为1的时候,段头中只有一个Master Freelists,而不存在我们希望的Process Freelists

不幸的是,绝大多数用户在使用MSSM的时候并没有设置Freelists参数,他们并没有留意到这种设置带来的负面影响。这种负面影响到底有多大呢?老白遇到过的一个最为极端的案例是一个移动公司的短信平台,这个平台每天需要插入的数据量在几千万条记录到几亿条记录,由于Oracle数据库使用的是8i,因此只能使用MSSM,在这个平台上我们进行了一个测试,在8个并发插入进程的情况下,如果FREELISTS设置为8,性能比FREELISTS设置为1 提高了5.7%。在一半的情况下,可能性能提升没有这么明显,不过如果Freelists参数设置不合理,造成1-5%的性能影响还是很可能的。

Freelists的机制设计的确实比较巧妙,似乎我们的所有问题都已经被解决了,不过细心的读者还会有一些疑问,那些已经标志为“满”的块怎么再次回到Freelists上呢?难道只要数据被删除了,块使用率低于PCTUSED,这个数据块就马上被放到Freelists上吗?这么做似乎也不太稳妥,一旦这个删除操作回滚了,那么岂不是又要再次把这个块从Freelists上摘除吗?实际上Oracle早就为这种操作设计了算法,这就是Transaction Freelists。一个段缺省有16Transaction Freelists,如果某个事物要修改这个段,首先会搜索Transaction Freelists,如果找到了这个会话的Transaction Freelists,那么就继续使用,否则这个会话就会继续找一个空闲的槽位,如果找不到空闲的槽位,这个会话就会试图去扩展一个新的Transaction Freelists,如果要扩展的时候,正好Segment Header中已经没有空闲空间了,那么这个会话就只能等待其他会话提交后腾出空闲的槽位。这种等待有点类似于我们前面说到的事务槽的等待,不过事务槽的等待产生于数据块中,而Transaction Freelists的等待是存在于Segment Header中。如果我们使用MSSM,并且Segment Header的等待较为严重的话,我们就应该检查检查是否是由于这个原因引起的等待。

当某个会话申请到Transaction Freelists后在某个数据块中删除了一些数据,这个数据块的使用率低于pctused参数后,这个数据块就被挂到Transaction Freelists上了,这个时候这个数据块可以被插入数据了,不过由于这个数据块只是在本会话的Transaction Freelists上,因此在这个事物提交之前,只有本事务可以在这个数据块中插入数据,只有等这个事物提交后,Transaction Freelists上的数据块才会被挂到Master Freelists的尾部,这个时候其他的会话也可以使用这些空闲块了。

是不是很巧妙的算法?Oracle通过这三种Freelists,十分好的解决了插入数据时的性能问题,将Freelists机制的瓶颈降到了最低。

对于MSSM来说,还有一个十分重要的参数Freelists Groups,这个参数一般来说被认为是OPS/RAC相关的参数,实际上这种认识也存在一定的片面性。不过我们还是先从这个参数在RAC环境下的应用说起。对于RAC系统来说,在MSSM环境下,Freelists的算法和单实例环境是十分类似的,了解CACHE FUSION机制的读者这个时候就会担心了,这种机制可能在RAC环境下产生严重的GLOBAL CACHE相关的性能问题。比如不同的实例上都会对某张表进行插入,那么如果INSTANCE 1上有一个会话在BLOCK 10中插入了一条记录,然后INSTANCE 2上有一个会话在BLOCK 10中插入了另外一条记录,INSTANCE 1再次在BLOCK 10中插入记录,这样的操作如果很多的话,那么就会成为一场灾难。这个数据块在两个节点中不停地来回传播,形��了GLOBAL BUFFER BUSY,这种数据块一旦躲起来,那么这个RAC系统的性能就会急剧恶化。

事实上,Oracle有足够的技术来避免这种悲剧的发生,Freelist Groups就是为解决这个问题而设计的。比如我们目前的RAC环境是一个2个实例的数据库,我们对某张表设置了Freelists Groups参数为2,那么这张表创建完毕后,在这张表的Segment Header中会有两个BLOCK,专门用于存储两组不同的Freelists(我们称之为Freelists Block),这种情况下,Segment Header Block里只有一个Super Master Freelists,上面挂载了这个Segment中的空闲块,而在每个Freelists Block中都有一个Master Freelists和若干个Process Freelists(由参数Freelists参数确定),在这两组Freelists上分别挂了一组空闲块,当某个实例上的会话需要插入数据的时候,会通过INSTANCE_IDPIDINSTANCE数量、Freelists Groups参数等因素来选择一组Freelists,从这组Freelists上选取空闲块。只要我们设置的Freelists Groups等于INSTANCE的数量,我们就可以确保每个实例都有自己独立的Freelists组,由于一个数据块只能挂载在一个Freelists上,这样就确保了不同实例插入数据时,不会选择不同的数据块(Freelists Groups大于Instance 数量一般也可以确保在大多数情况下不会出现不同实例共享相同的Freelist Groups,由于其选择算法较为复杂,我们这里不做详细的讨论)。

这种机制就很好的避免了我们刚刚所担心的问题,这是不是很美呢?而事实上不幸的是,我在十多年的优化工作中,还没有碰到一套系统为RAC环境设置了Freelist Groups参数,所有的系统都是用了缺省值,而Oracle的缺省值恰恰是每个段只有一个Freelists组。更为不幸的是,一旦段创建之后,Freelists Groups就是固定的,我们无法动态的扩展Freelist Groups,如果要扩展Freelists Groups,我们必须对��个段进行重建。因此在做数据字典设计的时候,开发人员应该事先为RAC环境设计好Freelist Groups参数,以避免今后扩展带来的麻烦。在考虑Freelist Groups参数的时候,我们不仅仅要考虑到RAC环境,而且要为今后RAC节点的扩展预留足够的Freelist Groups

看到这里,读者应该理解了Freelist GroupsRAC应用中的作用,而事实上,Freelist Groups不仅仅在RAC环境下有用,在一些极端条件下,这个参数在单实例环境中也能发挥作用。在一个插入并发量很大的环境中(比如有几十甚至上百个并发会话会对同一张表进行插入),我们可能经常会观察到这张表的segment header的等待,这种情况下,设置Freelist Groups大于1可以减少由于Freelist争用而导致的Segment Header的热块争用情况,多个Freelist Groups可以将多个对Freelists的并发操作分散在多个Freelists Block中,从而提高并发插入的性能。

我们在这一节中讨论了大量的FreelistsFreelist Groups参数在解决大并发量插入时的性能问题上的优点,这并不说明我们可以随便滥用这两个参数。这两个参数除了优点之外,也有一些缺点。多个Freelists可能导致数据块中的数据填充率变低,段的高水位推进过块,存储相同数量的记录,可能会占用更多的数据块。对于表扫描较为严重的应用来说,我们需要慎重考虑二者的正面和负面的影响,从而权衡使用这组参数。一般来说,在OLTP系统中,插入并发量很大的表,一般来说表中的数据量很大,应用访问这些表的数据的时候,大多数情况采用索引扫描,因此加大这组参数的副作用较小。而对于OLAP系统,我们切不可为了提高数据并发加载的性能而轻易加大这组参数,因为OLAP系统的数据经常需要进行全表扫描,这组参数的使用可能会影响全表扫描的性能。

谈了这么半天,可能有读者会说了,现在我们主流的数据库都已经是10g甚至11G了,从oracle 9i开始就支持自动段空间管理了,讨论手工段空间管理是不是已经没有多大意义了呢?事实上对于DBA来说了解一些MSSM的技术还是有意义的,一方面是我们很可能碰到8i的数据库,也可能碰到一些9i或者10g的数据库,它们是从8i升级上来的,可能很多表空间都是MSSM管理模式的。甚至我们可能为了规避某些BUG(比如说9iASSM表空间由于object reuse导致的ORA-600 [kcbget_xxx]ORA-600 [kcbnew_xxx]之类的BUG)而是用MSSM的表空间。甚至在某些极端的情况下,为了避开ASSMBITMAP带来的性能问题而反过头来是用MSSM(在绝大多数情况下ASSMBITMAP机制在性能上会优于Freelists管理模式,不过在某些特殊应用情况下,可能会反过来)。

通过上面的讨论,大家是否理解了MSSM下段参数的设置要点了呢?实际上,在具体的应用环境中,可能情况远比今天老白和大家一起探讨的要复杂的多,如何在纷繁的头绪中处理好这几个看似很简单,但是又很让人头痛的参数呢?这需要数据字典的设计者首先要对MSSM管理的机制十分了解,另外要对自己应用的特点十分了解,才能做出合理的选择。最后要提醒的是,当你无法做出合理的判断的时候,做个试验可能是比较明智的选择,到底哪种选择更好,应用系统说了算。

----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-22 9:45:55
  楼主   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
预告,下一节的内容是:3月23日 理解表的存储结构 (4)减少热块冲突的方法
大家希望老白讨论些什么内容可以提出建议
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-22 9:46:32
  2  楼   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
这是我昨天在飞机上写的一节,可能有些地方有些疏漏,如有问题请大家指出。
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-22 9:52:54
  3  楼   顶端
corey
等级:初入江湖
经验:95
信用:11
金币:220
发贴:1
精华:0
注册:2009-11-25
状态:离线
 (0)     (0)
corey的个人资料   发送短消息息给corey   发送电邮给corey   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
可以讲讲各种表之间的区别啊,heap table, iot, cluster table等
还想看看index的存储结构,特别是复合索引是怎么存的
IP:您无权察看 2010-3-22 13:48:30
  4  楼   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
这些内容可以有。别着急,还没讲到地方呢。光是一个表就够我写个把月了
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-22 13:50:04
  5  楼   顶端
corey
等级:初入江湖
经验:95
信用:11
金币:220
发贴:1
精华:0
注册:2009-11-25
状态:离线
 (0)     (0)
corey的个人资料   发送短消息息给corey   发送电邮给corey   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
有个问题,PCTUSED在ASSM中还是有意义的吧,并没有“逝去”
另,不提提INITRANS吗
IP:您无权察看 2010-3-22 14:11:24
  6  楼   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
PCTUSED在ASSM中已经没有用了,因为已经不存在FREELISTS了。INITRANS会在很多地方提到。实际上之前已经谈了不少initrans了
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-22 14:38:37
  7  楼   顶端
asmboy001
等级:初入江湖
经验:81
信用:7
金币:37
发贴:0
精华:0
注册:2009-12-21
状态:离线
 (0)     (0)
asmboy001的个人资料   发送短消息息给asmboy001   发送电邮给asmboy001   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
Freelist Groups 这个参数在10g rac里面还有效吗,
这个数据块在两个节点中不停地来回传播,形成了GLOBAL BUFFER BUSY,这个应该怎样处理呢
IP:您无权察看 2010-3-28 11:05:25
  8  楼   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
FREELIST GROUPS是和段空间管理的模式相关的,和具体的版本无关,10G仍支持段空间管理为手工模式。至于GLOBAL BUFFER BUSY的优化方案,在后面的章节中会介绍。最近事情很忙,今天参加了儿子的幼儿园活动,刚刚回家。春节后第一次有空和儿子一起过周末,感觉对家庭还是有些愧疚
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-3-28 21:25:15
  9  楼   顶端
大海
等级:初入江湖
经验:126
信用:17
金币:335
发贴:0
精华:0
注册:2009-4-28
状态:离线
 (0)     (0)
大海的个人资料   发送短消息息给大海   发送电邮给大海   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考(5) 3月22日 理解表的存储结构 (3)那些逝去的老参数
good
支持,重温了知识
IP:您无权察看 2010-4-1 16:22:00
  10  楼   顶端
11101/2页12
页面运行: 2005 毫秒

Powered by CWBBS 2.1  © 2005-2006 Cloud Web Soft
  Email:webmaster@justdb.cn