本帖最后由 vage 于 2013-3-14 23:46 编辑
DBWR原理分析暂告一段落,接下来继续写书。花费两周,形成的可用性结果不多,也就检查点写和LRUW写比例问题。但通过这次分析,理解了DBWR工作机制,脏块如何被整理成Batch,IO如何合并,块何时进入LRUW,又何时进入AUX LRUW,Obj-Q的巨大作用等。虽然研究结果大部分没有用,但明明白白维护Oracle,一直是我追求的目标。
仔细回味一下,有一种刚看完一季悬疑侦探剧的感觉,经过追踪、分析,结果一个个水落石出,但最终的大Boss还逍遥法外,还有艰辛苦的续集在等着我。道之所在,虽千万人吾往矣。
简单总结一下,等书写完,有了时间,详细为大家总结一下。
1、IO情况:分Batch,将相邻的块合并,异步的提交IO。每个Batch中IO是异步,Batch与Batch之间为串行。比如,某个Batch是100个块,发现相连的块有50个、40个、8个,还有两个块不相连,将50个块从Buffer Cache的不同位置复制到共享池中一块连续的大内存中(此时如果内存不足,会报4031),提交异步IO,将此连续的大块内存写磁盘。再将40个块从Buffer Cache的不同位置也复制到共享池中一块连续的大内存,提交异步IO,等等。对于不相连的块,不在复制,直接提交异步IO从Buffer Cache写磁盘。然后等这个Batch中所有IO完成,开始下一个Batch。所有,Batch与Batch之间,是同步、串行的。
2、从检查点队列写时的IO合并算法:依赖Object链表。我们都知道Buffer Cache有条Object链表,用作Truncate、Drop对象时处理对象的块。这条链表又分脏与不脏两种。在增量检查点机制中,DBWR触发写操作时,会将脏块从检查点队列移至各个对象的脏对象链表中,在脏对象链表中按块的文件号、块号排序,就可以找到连续的块。
这种算法的确很巧妙,如果将所有脏块一起排序,参与排序的块太多,耗用内存太大,而且有可能影响性能。而不同对象的块,相邻的可能很低,将块按对象分门别类,再排序,的确是个好方法。
根据DUMP结果,块在检查点队列时,状态为obj-flags: object_ckpt_list,当要写脏块时,状态为:obj-flags: object_write_list,同时objq的链表位置有变化。
3、块何时进入检查点队列:当块变脏的时候。
4、块何时进入LRUW:服务器进程在LRU中搜索可重用Buffer时,遇到脏块,会将脏块移至,等待三秒DBWR超时时,LRUW中的脏块被DBWR写磁盘。注意,如果进程在LRU中遇到TCH大于等于2的脏块,不会将其移到LRUW,而会移到热LRU。另外,被移到LRUW中的脏块,将从检查点队列中去除。
被移至LURW的块数,被记录在v$sysstat中dirty buffers inspected资料。此资料值如果持续升高,物理读、CR块构造性能一定会受影响。
5、块何时进入AUX LRUW:DBWR收到服务器进程消息通知后,马上会将LRUW中的脏块移至AUX LRUW,然后进行分Batch、IO合并,写磁盘。写完成后块被放入AUX LRU。
6、v$sysstat中的相关检查点的资料有两个:physical writes non checkpoint、DBWR checkpoint buffers written,谁才是检查点写的脏块数呢?是第二个:DBWR checkpoint buffers written。想知道你的数据库有多少脏块是从检查点写到磁盘的吗,DBWR checkpoint buffers written可以告诉你答案。
physical writes - DBWR checkpoint buffers written = 从LRUW写的脏块。从“LRUW写的脏块数”和“检查点写的脏块数”的比值,也是一个性能指标。是衡量检查点的一个重要指标,这个指标差,dirty buffers inspected会很高,进而产生Free Buffer Waits,影响物理读和构造CR块的性能。
阿里的数据库,大部分库检查点的比例,都在80%以上。
差不多了,暂时记录一下,等以后详细为大家整理。