中国网管论坛's Archiver

iamlargelove 发表于 2007-8-18 20:51

再再 发一个 tablespace manage

表空间管理

一。表空间管理
ORACLE表空间管理现在有2种管理方法,一种是字典管理,一种是本地管理
在谈这2种管理的区别前,我必须转到表空间的结构,因为如果不对表空间的结构有所了解,是无法理解这2种管理的差距的。
表空间(tablespace)----->段(segment)------>区段(extent)----->块(block)  
表空间既然是由块构成的,那么是否对表空间的管理其实就是对块的管理呢? 错了,完全不是这样。首先要知道当你的一个对象空间不够的时候,也就是要扩展的时候是直接扩展区段(extent),ORACLE并不希望我们涉及到BLOCK (当然也是可以的,只不过不推荐而已)。 既然在分配的时候是直接分配区段,那么我们通常所说的表空间管理,其实指的是对extent的管理。
问题出来了,  何谓表空间管理?或者说到底对extent需要怎么样的管理?这东西到底在使用过程会发生什么?
假设你创建一个表,首先分配一个区段给你,这个区段是怎么分配的?直接拿去就可以吗? 不是的,如果直接拿的话,请问你怎么就知道这个区段是空闲的,或者说这个区段没有数据呢?问题就在这了,所以ORACLE必须去使用一个方法让拿区段的对象知道哪里是空闲。
进入正题了:
1。字典管理
在以前使用字典管理方法,所谓字典管理就是在ORACLE系统中有一个底层表在维护着所有的extent,或者直接说是维护block吧。当你要新增加一个extent的时候,ORACLE需要在这个表中查找哪一个extent是空闲的(最早查到的空闲就给出去,不是把所有空闲查出来再分配出去。),然后把这个查找到的extent利用SQL语句置为使用状态,如果某个extent以前是使用的,但是由于删除数据又空闲了,那么ORACLE又要利用SQL去置为空闲状态。这种SQL被称为递归SQL。
或许你现在还感觉良好,觉得不就是执行几个SQL嘛!对,就是执行几个SQL而已,可是要知道对字典表的修改必须是串行的,几个对象同时需要空间时必须一个一个来,否者不就乱了嘛。
当一个非常繁忙的系统不停的申请空间,然后又释放空间,可想这种串行的方法会导致什么? 那就是排队,等待。现在你还感觉良好吗?
2。本地管理
本地管理就是在每个表空间维护一个位图(注意是每个表空间都有,所以在一个表空间申请空间不会影响别的表空间),0表示空闲,1表示已使用。当你需要空间,只需要在表空间查找一个为0的extent,然后数字变为1就可以。反则同样道理。
疑问: 那么对这个位图的操作是串行的吗?可以想象应该是串行的,但是没关系,这种操作非常快,比起操作SQL来讲非常快。

以上谈到的是表空间在分配对象空间(extent)时所做的管理方式,其实我们知道表空间不管怎么讲都是由块构成的,所谓由extent构成只不过是一种逻辑上的说法。
于是由出现了segment的管理问题(其实所谓段管理就是block管理,不要被迷惑了,好比表空间的管理是对extent管理)
问题:segment需要管理什么?也就是块需要管理什么?
二。segment管理
segment管理分为2种方式:
1。手动管理

所谓手动管理是你在新建一个对象时,必须指定诸如FREELISTS,PCTFREE,PCTUSED参数。
2。自动管理
自动管理不需要FREELISTS和PCTUSED了。 但是PCTFREE还是需要的。

那么到底什么是FREELISTS,PCTFREE,PCTUSED呢?接下来先解释这几个术语。
PCTFREE:一个block的使用空间达到总block空间的多少就不允许插入数据(为什么不允许插入?因为你        要留着空间去更新啊,如果没有空间了,下次你要更新这个块的某行,会导致行迁移,这个行迁        移很讨厌,尽量避免)
PCTUSED:当一个block的空闲空间达到多少时又可以插入数据(是不是有点头晕了?继续看就明白了)
FREELISTS:维护着HWM以下的块
这里引用一个网上朋友的话(写的很好,我看TOM写的看的头晕,还是咱们中国人说话简单明了):
*******************************************************************************************
我们知道Oracle数据库的读取单位是数据块(Block),而一个Block是否允许被写入数据是基于一定的空闲度,这就是大家知道的pctfree和pctused存储参数设置。
假设pctfree=10, pctused=40,这就表明当一个Block的空间使用率达到了90%(100-pctfree)时,这个block就不再允许被用于新增数据(insert),而保留下来的这10%的空间则被预留为行更新(update)所可能需要的空间扩展,我们说此时这个block就从freelist上被摘走了(实际上还有另外一种情况,就是当块剩余空间不足以插入一条记录并且该块的使用率已经超过了pctused定义的值并且该块位于freelist header处时,该块也会从freelist上被摘走,术语称为UNLINK)。当有数据删除(delete)的时候,只有该block中的数据被删除到一定的程度,该块才会重新被加入到freelists中,而这个程度就是pctused参数定义的数值,如我们这个例子中,只有块中的数据降低到40%以下的时候,该块才被重新允许用于新增数据。
通过上面的描述,可以知道所谓freelists,就是一个指定了所有可以用于insert操作的数据块的列表。存在在这个列表中的数据块才能用于insert操作,一旦一个数据块无法用于insert(达到了pctfree参数指定的限度)则立刻从这个列表中被摘除。freelists的作用就在于管理高水位标志(HWM)以下的空闲空间。
注意:freelists只是管理高水位标志以下的空闲空间,而实际上一个segment可用的空闲空间包括两种类型:
1.  已经分配给这个segment但是从来未被使用过的位于高水位标志之上的blocks
2.  位于高水位标志之下,被链接在freelists上的blocks
*******************************************************************************************

现在假设你明白了FREELISTS的含义。我们说了,当你执行插入的时候,或者说当你需要空闲block的时候你是不知道哪个block是空闲的(这个和表空间分配extent是一个道理),那么你要去拿一个block或者说拿一个空闲空间必须去FREELISTS查看,看哪个地方可以让你插入数据。
问题又出来了:我们说对系统结构的修改都是串行执行的,你去拿一个block当然这个时候不能允许别人也去拿同样的block。所以这个地方会有LATCH,那就是锁。
不过非常高兴的是,ORACLE允许多个FREELISTS,可能你会问:多个? LATCH才不管你有几个呢?反正你要拿就要等待。别急,这一次ORACLE才用的方法比较聪明,假设你有100个块,然后你分了3个FREELISTS,那么可能是这样的。主FREELISTS有50个块,其他2个辅助FREELISTS每个有25个块。所有的块不同哦。
那么当有一个LATCH在主FREELISTS,那么你可以去其他2个辅助FREELISTS啊。这样就不会产生等待啊。不过问题又出来了,如果辅助FREELISTS块被分配光了呢?这里要明白他不会去别的FREELISTS拿,而只会去主FREELISTS(这也是为什么分 主 和 辅 的原因)。
那么我还有一个问题:既然这样我分他个100个,甚至1000个FREELISTS不就OK拉。
是这样吗? 如果这么容易就不要你管理了,随便找个扫地的阿姨就可以管。
如果某个FREELISTS空间用完了,那么去主的FREELISTS拿block,一直这样拿,知道主FREELISTS也没有了?但是其实可能其他辅助FREELISTS还是有block的。
这个时候主FREELISTS需要申请新的extent(这里终于和表空间管理联系起来了)。
由此可知,如果不停的发生这样的情况,主FREELISTS可能会不停的扩展extent,其实这种扩展对系统不会有影响,因为本地表空间管理很快,但是会出现浪费空间的情况。(不过我觉得没太大问题,不就是空间而已)
这里主要谈的是FREELISTS,那么还有PCTFREE和PCTUSED。
如果把PCTFREE设置太大,浪费空间,设置太小出问题。所以必要找到一个折中的方式来管理。

总的来说从大的结构下管理表空间就是这样了。
下一部分会针对具体的表空间的利用率,碎片等问题进行分析。

页: [1]

Powered by Discuz! Archiver 6.1.0  © 1999-2008 bbs.bitsCN.com