引言
晚上没事,翻了翻老盖写的书,看到了buffer cache工作原理部分,觉得挺有意思,以此文章作为纪念,对Oracle部分buffer cache工作原理做个简短描述,很多DBA都不是太懂buffer cache flush dirty block原则,今天主要聊聊刷新缓冲区缓存将导致脏块写入磁盘的一些工作原理,文章很短,请耐心看完。
首先创建一个示例测试表,我们尽可能让它一行占用一个block,为了补充大家对于开发知识的短板,我们利用简单的匿名块+动态SQL+绑定变量创建:

02
获取对应数据文件号和数据块号:

03
查询x$bh数据字典,我们有一个当前块(状态=xcur)。在SQL变量提示符中输入刚才查询到的16号数据文件以及132号数据块内容:

04
这时候,我们做一笔更新操作,让这个132号数据块变脏,记住,不要提交事务,这样关于更改的信息就不会被写入重做日志。
注意:不要提交,以免事物信息写入到redo log

05
新开一个session,做同样的查询操作到x$bh下:

注意:1.STATE中我们在如何构建一致性读文章中有详细介绍,buffer的几种状态,回顾一下:
1.1free :目前未使用
1.2xcur :独占
1.3scur :current当前共享模式
1.4cr :一致性读
1.5read :从磁盘读取
1.6mrec :media介质恢复模式
1.7irec :实例恢复模式
06
下一步,我们开始刷新高速缓存:

07
这个时候,再次查询缓冲区缓存,你会发现BUFFER STATE变成了free目前未使用状态:

08
这个时候,我们从没有提交的会话查询T_600_DEMO测试表,注意,将显示更新后的行。

09
再一次检查当前版本的块((state=xcur)是否已读入缓冲区缓存

注意:
1.从上两部分我们可以明确,物理读= 0,因为当前块已经在缓冲区缓存中。
2.一致的读> 0作为撤销表空间已被读取,以构造cr块。
总结
1.其实早在Oracle9i里,Oracle已经提供了一个内部事件,用以强制刷新Buffer Cache,其语法为:
alter session set events 'immediate trace name flush_cache level 1';
alter session set events = 'immediate trace name flush_cache';
2.同样的,也可以在系统级别alter system set events = 'immediate trace name flush_cache';刚才我们演示的是oracle 10g版本以后的方法alter system flush buffer_cache;


600团队
点亮梦想,拒绝平庸