SQL Server的数据缓存管理

    以下缓存机制应用于SQL Server 2005。

    数据高速缓存区主要用于缓存数据库文件的数据页和索引页,多个用户可以共享数据。当其他组件需要内存时,就可以向缓冲池申请缓存页面。这样可以有效的减少IO次数,显著减小相应时间。当缓存区到达GB级别时,显然使用线性扫描的方法来寻找一个数据页的方法是十分低效的,所以需要引进哈希机制来支持数据的高速访问。一个哈希表包含一组指针指向缓存页面,当一个哈希页面容纳不下哈希表时,那么指针会指向下一个哈希页面。

     数据高速缓冲区的管理,包括脏页的持久化,页面的替换等模块。SQL Server维护一个由自由页面地址组成的链表,由一个工作线程管理改自由页面链表。缓冲区中每个页面都有一个头部,包含其最近两次被引用的信息和一些状态信息,包括改页是否是脏页。页面的替换算法使用的是LRU-2(考虑页面的最近两次引用的LRU)的算法,该算法个人认为是综合了LFU(least frequency used)和LRU(least recently used)的优点,住俺隔壁的余总总结的好(虽然他是转的别人的,囧):

LRU是将上一次使用时间最短的数据优先存放在cache中. LFU则是将过去使用频率高的数据优先保存在cache中.这两种算法代表了两个极端,LFU使用数据的访问频率,有利于数据的总体优化使用,但不利于数据访问方式的变化和猝发访问.LRU依据最近一次的访问时间,能较好地适应数据访问的变化,但只是在访问时间上的局部优化,没有考虑数据长期的访问特性.有一些算法试图在数据的访问时间和访问频率两方面达到平衡.如LRFU算法给近几次访问时间乘上一个与访问频率有关的权重,以加权值来取得两者之间的平衡.LRU-K算法则是使用最后第K次访问时间来扩展LRU算法,依靠K值的大小进行平衡.它们都是对访问时间的修正,是对LRU算法的改进.

 

    在操作系统课程中,我们曾经比较详细的比较了这些替换策略的优劣。LRU更能反映程序的局部性定理,性能当然要好。但是在数据库应用中,很多时候要考虑到全局的总体的内存访问。在O'Neil的论文中,举了一个例子提到了数据页和索引页在内存中的B-树结构,如果采取LFU的话。。。不解释哈。如果采取LRU的话,将有极大可能把索引页替换出去,而这样的做法是效率低下的。如果采用LRU-K的方法的话,将能很好的平衡,既减小了将索引页替换出去的可能性,又考虑到了程序的局部性。但是LRU-K算法也并不是所有Cache替换策略的银弹。具体采用何种策略视具体应用而定。

    当SQL Server在做缓存页替换的时候,它会检查当前页面是否是脏页,如果是,写回磁盘。在写回磁盘前先写日志记录改动,这是对可靠性的一个考虑。被释放的缓冲区页面返回给自由缓冲区列表。缓存替换的发生时间在当工作线程发现自由区的大小小于某一定阀值时。在写入一个脏页时,它会检查是否有在物理上与当前页相邻但是都是脏页的成片数据。如果有的话,工作线程会将他们一次性写入,这种聚集写入显著提高了IO效率和保证了一定的可靠性。

   现在来考虑可靠性,假如现在服务器因为故障Down机,内存中有很多脏页没写入怎么办?所以必须由一个线程每隔固定时间检查一次缓存,将当前的脏页全部写入磁盘,这个过程称为检查点。缓存池越大,在检查点完成之前某个缓存块变脏的可能性越大,所以使用一个与每一个页面关联的比特位做标志。当检查点开始时所有的比特位设置为0或者1,当一个检查点检查页面时,它会把标志置为相反值。当检查点遇到一个相反值时,不会将该页写入磁盘。同样因为与其他脏页物理相邻而被聚集写入了的页面也会置标志为相反值,不会将其二次写入。

 

posted @ 2008-12-02 11:47 流浪de小F 阅读(293) 评论(0) 编辑 收藏