技术提高能力,沟通开拓视野

统计

留言簿(2)

积分与排名

阅读排行榜

评论排行榜

浅析SQLSERVER数据库文件存储机制

数据存储是SQLSERVER数据库比较核心的知识,同时网络上相关的参考资料也比较少!近段时间,通过微软的WebCast学习以及自己查询资料,
将自己对SQLSERVER数据库在数据存储方面的理解整理下来,一方面希望能加深自己的印象,另一方面也希望能给其他的朋友提供相关的参考!

一:存储文件类型
   SQLSERVER有两种数据存储文件,分别是数据文件和日志文件。
其中:数据文件是以8K(=8192Byte)的页面(Page)作为存储单元的。
而日志文件是以日志记录作为存储单元。

二:页面类型
   SQLSERVER中页面类型有8种,具体每种类型的详细说明,见下图:


三:页面结构
   SQLSERVER中,页面结构如下图:
  
    其中:数据页面页首:96个字节,保存着页面的管理信息,比如该页面所属于哪个物理文件。
         数据区:对应于上图中所有数据行的总区域,存放真正的数据,是以Slot为单位。一个Slot就是对应于一条数据记录行,从0开始编号,以16进制反序保存,Slot0,  Slot1....。
         行偏移数组:用于记录该数据页面中每个Slot在数据页面所处的相对位置,便于定位和检索每个Slot在数据页面中的位置,数组中每个记录占两个字节。

四:存储分配单位:盘区(扩展 Extend)
     虽然SQLSERVER中数据文件的标准的存储单位是页面(Page),但为了减少频繁的读写IO,在表或其它对象分配存储空间,不是直接分配一个8K的页面,而是以一个盘区(Extend)为存储分配单位,一个盘区为8个页面(=8*8K=64K)。

五:盘区类型
      在SQLSERVER存储分配时,为提高数据库性能,不是以页面做为分配单位而是以盘区做为分配单位。这样虽然减少了频繁的IO读写,提高的数据库性 能,但却导致出一个新问题,那就是在存储那些只有少量数据,不足8K的对象,如果也是分配给一个盘区,就会存在存储空间上的浪费,降低了空间分配效率。
      为解决上述问题,SQLSERVER定义了两种盘区类型,统一盘区和混合盘区。
      其中:统一盘区只能存放同一个对象,该对象拥有这个盘区的所有页面        
           混合盘区:由多个对象共同拥有该盘区。
      在实际
为对象分配存储盘区时,为了提高空间利用率,默认的情况下,如果一个对象一开始大小小于8个页面,就尽量放在混合盘区中,如果该对象大小增加到8个页面后,SQLSERVER会为这个对象重新分配一个统一盘区。

六:盘区管理机制
    为了可以准确无误的实现上述的盘区分配策略,SQLSERVER使用了GAM/SGAM管理盘区机制。
    其中:GAM(全局分配映射页面),专门用来管理盘区,记录数据文件的盘区使用情况。一个GAM页面的大小也是8K,除去96个字节的页头,还有8*1024-96=8096(byte)=64768(bit),每个bit用0/1来表示这个盘区有没有空闲空间。
具体含义是:如果这个位是 1,则盘区可用;如果这个位是 0,则盘区已分配。一个盘区是64K,那么一个GAM页面可以管理64768*64=4GB的空间。也就是说,如果数据文件的大小小于4GB,只用一个GAM页面就可以管理,超出4GB后,才会增加第2个GAM页面。
    SGAM(全局共享映射页面),专门用来管理混合盘区,同样的,一个SGAM也可以管理4GB的数据文件。每个位中0/1表示的含义也与GAM中的一样。GAM与SGAM对同一盘区的管理参数搭配如下图:
    

    定义好管理盘区机制后,SQLSERVER中是如何给一个对象来分配盘区呢?
    简单来说,SQLSERVER会综合GAM和SGAM中盘区信息,寻找一个合适的盘区进行分配。
   
在对一个对象分配盘区时,首先根据大小来确实是分配新的统一盘区还是分配混合盘区。
     若 要分配新的统一盘区,SQL Server 在 GAM 中搜索是 1 的位,然后将它设成 0。
     若要查找有可用页的混合盘区,SQL Server 在 SGAM 中搜索是 1 的位。
     若要分配一个新的混合盘区,SQL Server 在 GAM 中搜索是 1 的位,并将它设置为 0,然后将 SGAM 中相应的位也设置为 1。
     若要释放盘区,SQL Server 应确保 GAM 位设置为 1 而且 SGAM 位设置为 0。
     SQL Server 内部实际使用的算法比这里叙述的算法要复杂,但道理大致如此。


七:通过DBCC命令查看数据页面信息
     数据存储相关的概念就是以上6点,全是理论性知识,但我们可以通过未公开的DBCC命令,直接查看某个数据页面的内容,得到直观上的数据存储信息。
     具体DBCC命令是DBCC PAGE.
     简单的使用例子如下:
   //查看数据页面的内容的方法
    --打开查看数据页面的开关
    dbcc traceon(3604) //打开跟踪标记
    dbcc Page(northwind,1,100,1) //打开northwind数据库,第101个页面的信息

posted on 2007-10-23 21:34 Alligator 阅读(1611) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。