数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
[Freelists Internal] 关于Freelists和Freelist Groups的研究

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

1。如果表空间不指定SEGMENT_SPACE_MANAGEMENT AUTO,仍然会使用Freelists和Freelist Groups来管理Free Block。

2。默认的Freelists和Freelist Groups均为1。Dump Segment Header Block可以发现有一个Freelists,称为mater free list,每个segment至少有一个master free list。如:
SEG LST:: flg: USED   lhd: 0x01c0000b ltl: 0x01c0000b
flg(flag)表示该freelist是否被使用
lhd(list header)表示位于该list中的第一个可用block的dba
ltl(list tail)表示位于该list中的最后一个可用block的dba,这个block必定位于HWM之下。
每个位于list中的block header中存在一个指针指向下一个可用的block,如:
fnx: 0x1c0008b

3。如果创建segment时候指定多个freelists,比如设置freelists 2,那么在segment header block中总共有3个free list,其中1个是main free list,另外2个是process free list。如:
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: USED   lhd: 0x01c0008b ltl: 0x01c0008b

4。只有当DML语句使block降到pctused参数指定值之下时,才会动态生成transaction free list记录这些block的dba。而一个新分配的block则始终是位于process free list或者main free list中的。每一个transaction都会动态创建自己的transaction free list,直到达到segment header block size的限制。如:
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000 
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000 
SEG LST:: flg: USED   lhd: 0x01c0008d ltl: 0x01c0008d 
XCT LST:: flg: USED   lhd: 0x01c0008c ltl: 0x01c0008a xid: 0x0008.01f.000003d2
可以看到当删除数据使block重新可用的时候,位于freelist header处的是最后被分配的block,最先分配的block则处于freelist tail处。其中xid记录的是这次DML操作的transaction id。
问题:为什么最后被分配的block被放置在freelist header处?

5。当重新insert数据或者发生row  migration的时候,会从transaction free list header开始使用已经释放了的空闲block。如果transaction free list中没有 previously freed blocks,那么就从process free list中寻找,因为可能定义了多个freelist,所以到底从哪个free list中找,算法是(P % NFL) + 1,其中P表示DML操作进程的Process ID,NFL表示Process free lists number。如果在process free list中找不到或者根本就没有process free list(segment只有一个freelist的情况),那么再从main free list中找。仍然找不到的话,返回去再查transaction free list,判断其中的transation是否已经commit,如果已经commit了,则把这个transaction free list的flag标志为unused,同时把位于这个list中的所有block合并到main free list中。
问题:什么情况下transaction free list中的事务已经commit,但是却仍然没有previously freed blocks?

6。所有的freelist中都没有找到可用的空闲块,此时segment就要开始分配新的extent,提升HWM。新分配的块被放置在main free list中,如果有process free list存在,那么在使用前,根据数据请求量,每次最多转移5个block到相应的process free list中,也就是在存在多个freelist的情况下,一次空间的请求总是读取transaction free list或者process free list,而不会直接从main free list中读取。
从这个地方我们可以看到虽然多个freelist可以缓解多个并发的session同时更新一个segment的需求,但是如果只有一个main free list,那么在从main free list把block转移到process free list的这个环节上仍然会出现争用,此时就是多个freelist group发挥效果的时候了。所以多个freelist group不仅对于RAC环境有效,对于单个instance也是可以缓解一定的资源争用的。但是无论是多个freelist还是多个freelist group,都不可避免地会产生空间浪费的副作用,在某些特殊场合下甚至会让一个segment急速地增大。

7。对于freelist和freelist group,Tom在《Effective Oracle by Design》中有个比喻。想象有一台饮水机和源源不断的急需喝水的人们,一台饮水机就代表一个freelist,而一个想喝水的人就是一个准备向segment中插入数据的会话。如果我们只有一个饮水机,那么所有想喝水的人都必须要排成一队,然后前一个喝完了下一个才能喝,这就产生了争用。设想一下我们现在放置了10个饮水机,很明显人们可以排到10个队伍中的任何一个队伍里,毫无疑问效率大大加快了。这时瓶颈又出现了,就是如果一个饮水机里的水被喝完了,就得给这个饮水机加水,此时如果只有一个加水员(这就是一个freelist group),那么加水的速度可能就会跟不上了,添加freelist group就是增加加水员,增加到2个,每个人负责5个饮水机,OK,效率又提升了。
对于空间浪费的负面影响,我们继续设想一下。来了一个十分能喝水的人,他把住一个饮水机不停地喝,喝完了,引水员就加水,又喝完了,又加,即使是其它的9个饮水机里都是满满的水也没用,因为这个人一旦从某个饮水机中开始喝水,除非到喝饱离开为止,他是绝对不会换到另外一个饮水机上去的(一个会话一旦从某个freelist中开始读取空闲块,就不会再使用其它的freelist,即使其它的freelist表示还有很多的空闲块)。

8。设置了多个freelist group,就会产生freelist blocks,这些block紧跟在segment header block之后,假设我们设置了freelist groups 2,那么segment的第一个块是segment header block,第2,3个块则都是freelist block。首先在segment header block中存在1个freelist,称为Super Master Free list或者Segment Master Free list。而在每个freelist block中又都存着1个master free list,还存在指定的process free list,块的剩余空间则全部留给transaction free list使用。在单个instance中选择freelist group的算法是(P % NFB) + 1 ,其中P表示DML操作进程的Process ID,NFB表示Freelist Groups number。在RAC环境中的算法则更加复杂,此处不作讨论了。
DUMP freelist block的一些输出如下:
frmt: 0x02 chkval: 0x0000 type: 0x16=DATA SEGMENT FREE LIST BLOCK WITH FREE BLOCK COUNT
  blocks in free list = 5 ccnt = 0
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
  SEG LST:: flg: USED   lhd: 0x01c00116 ltl: 0x01c0011a
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000

总结一下:如果我们定义了storage(freelists 4 freelist groups 2),那么在segment header block中有1个Super Master Free list,有2个freelist block,每个freelist block中又有1个master free list和4个process free list,当SML操作产生将本来不是free的block重新标志为空闲时,动态产生一个transaction free list。所有的free list record中都只记录flag,list header block dba和list tail block dba,整个freelist是由存在于每个位于列表中的block header中指向下一个free block地址的指针这样类似链表的结构来完成的。

本文大部分知识来自:Ixora和Metalink

相关链接:Data Blocks and Freelists




相关文章

相关软件