深入内核:认识隐含参数_db_block_max_cr_dba

何剑敏

Oracle ACS 华南区售后团队,首席技术工程师。多年从事第一线的数据库运维工作,有丰富项目经验、维护经验和调优经验,专注于数据库的整体运维。

_db_block_max_cr_dba 这个隐含参数的作用是控制每个block(即一个dba下,或者说x$bh.dbablk)的最多cr块的个数。默认值是6(5个CR+1个XCUR)。

当产生一致性读(CR)的时候,session会从前镜像读取块,加载到buffer cache中,加载的这个块,我们叫CR copy。保留多个版本的CR,可以缓解对buffer中block的并发争用(buffer busy wait),避免多个session同时读取一个buffer block。但是如果版本过多,挂在一个hash chain下的block太多,又会造成CBC latch的争用。所以oracle选择了6个版本。我们来测试一下CR copy的特性(数据库版本11.2.0.4)

数据初始化

检查初始情况

刚刚启动的时候,我们发现file#=4,block#=1365没有在buffer中。

开始构造一致性读:

session 1

session 2

当开始DML之后,block中数据文件中加载到buffer中,此时一定会有一个xcur的block,和cr block。这是因为DML is always performed on the current copy of the block (Status=xcur).

xcur的block表示当前已经被修改过的block,是最新的block,注意DI列(Dirty列)已经是Y,表示这个block是buffer中的脏块。cr block是在update之前,在内存中copy原来的xcur的block。我们看cr block的CR_SCN_BASE是update前一瞬间的SCN,即2687527。

即当update发生的时候, (1)如果块在buffer中(块的状态为xcur),那么copy一份这个在buffer中的xcur的块,copy出来的块是cr块。更新这个块,且这个块的标记还是xcur。 (2)如果在buffer中没有这个块,那么将这个block从磁盘读到buffer中(此时状态为xcur。这个过程,类似进行了一次没有一致性读的select,select的时候,当前块状态也是为xcur),将buffer中的xcur块,做一份copy,copy出来的块成为cr块,更新这个块,且这个块的状态还是xcur

由于刚刚进行了update,且没有commit。所以现在的select是需要进行一致性读。

session 3:

SQL> select * from t1 where c1=1;

session 2:

第一次的select,oracle一次性创建了2个CR block,分别是在SCN 2687545和SCN 2687546的时候。这个时候,由于是需要一致性读,因此这次的select是从前镜像读取,从undo中读取,所以,也可以看到这个前镜像块是从undo的那个块上读取,可以看到有UBA(undo block address)的file id,block id和sequence。file id为3,是在undo tablespace上。

session 4:

SQL> select * from t1 where c1=1;

session 2:

第二次的select,oracle只创建了1个CR block,分别是在SCN 2687575的时候。 读取的是在undo上的同一个UBA file id,block id和sequence,所以,在undo文件上的块是同一个块,但是在buffer中,cr块目前已经有3个cr块了。另外还有一个cr块,但是这个块是在做update的时候,对于该session来说在update之前的xcur的copy。不是从undo文件中读取的block。

session 5:

SQL> select * from t1 where c1=1;

session 2:

第三次的select,oracle只创建了1个CR block,分别是在SCN 2687595的时候。 读取的是在undo上的同一个UBA file id,block id和sequence,所以,在undo文件上的块是同一个块,但是在buffer中,cr块目前已经有4个cr块了。

另外我们注意到,oracle已经把第一次做update的时候,SCN 2687527的cr块刷出去了。这个被丢弃的CR block,对我做update的session来说,已经没有用处,因为当前session的block的值已经更新,当前session所需要的block是xcur的那个block。而对已其他session来说,由于还没有commit,需要读取前镜像,可以直接做第一次和第二次cr block的copy;或者直接从undo中加载。

session 6:

SQL> select * from t1 where c1=1;

session 2:

第四次的select,oracle只创建了1个CR block,分别是在SCN 2687615的时候。 读取的是在undo上的同一个UBA file id,block id和sequence,所以,在undo文件上的块是同一个块,但是在buffer中,cr块目前已经有5个cr块了。

session 7:

SQL> select * from t1 where c1=1;

session 2:

第五次的select,oracle只创建了1个CR block,分别是在SCN 2687643的时候。 创建这个CR block的时候,把当前cr block列表中最早的SCN 2687545的block丢弃了。只保留5个CR block。

至此,我们看到,不同的session的select,对cr block的影响: update但不commit,在update时产生一个cr block。 第一次select从undo获得前镜像产生2个cr block,当前共3个cr block 第二次select再产生一个cr block,当前共4个cr block 第三次select再产生一个cr block,且丢弃update时的cr block,当前共4个cr block 第四次select再生产一个cr block,至此已经有了5个cr block和1个xcur block 第五次select再产生一个cr block,丢弃第一次select产生的第一个block,只保留5个cr block和1一个xcur block 再后续select的话,每产生一个cr block,丢弃最早的cr block

我们再来看看flush buffer cache的影响: session 2:

session 8:

SQL> select * from t1 where c1=1;

session 2:

我们看到,flush buffer cache之后,xcur的block,即标记为dirty的block也被刷出buffer cache,所有的buffer block都是显示free。

但进行第一次select的时候,被修改的xcur block,还是从db file加载到内存,且被记录成dirty的block。另外,select出来的前镜像,也从undo加载到内存,形成第一个cr block。

到了这个,顺便问个问题,现在都流行database in memory,如果我的内存是256G的,能放得下256G的database吗?读了上面的问题,相信你已经有了初步的答案。:)

---the end

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2016-09-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ImportSource

Gitlab.com宕机始末

接上集:Gitlab.com误删数据最近动态:恢复60% 14小时前 数据库恢复60%; 13小时前 gitlab在国外某非著名视频网站直播自己的数据库恢复进...

3576
来自专栏ThoughtWorks

如果有10000台机器,你想怎么玩?(一)概述 | TW洞见

今日洞见 文章作者来自ThoughtWorks:高清华。 本文所有内容,包括文字、图片和音视频资料,版权均属ThoughtWorks公司所有,任何媒体、网站或个...

2646
来自专栏张戈的专栏

服务器日志备份超节省空间的思路

这两天,监控频繁发来服务器磁盘空间 90%+的报警,打扰睡觉不说,塞得满满的总是不舒服的。刚来公司才 20 天,对于部分细节上的运维了解得还不是很到位,比如这备...

3286
来自专栏Java技术分享

java系统高并发的解决方案

一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要...

2169
来自专栏大魏分享(微信公众号:david-share)

浅谈互联架构下的各种缓存技术

面对巨大的客户端访问量冲击,怎么办? 当业务系统收到突发大流量冲击的时候,怎么办?例如,双十一、双十二,银行遇到的突发交易请求;或者网站遇到突发流量访问,怎么处...

4424
来自专栏数据和云

静默错误:Oracle 数据库是如何应对和处理的 ?

说明:关于本文提到的所有参考文档,一律上传分享,关注本公众号回复 122arch 获得。

662
来自专栏CSDN技术头条

OpenStack实战系列:漫谈Neutron 的架构

一.前言 由于OpenStack Neutron项目本身的高度复杂性和抽象性,加之作为一名初学者,其理解能力有限。因此这里,阐述的仅是凤毛麟角而已,其目的是帮助...

2755
来自专栏杨建荣的学习笔记

一条insert语句导致的性能问题分析(二)(r8笔记第43天)

今天对之前描述的问题一条insert语句导致的性能问题分析(一) 进行了进一步的补充。 有一条insert语句的主要性能瓶颈在于insert子句中的查询语句,查...

2885
来自专栏Laoqi's Linux运维专列

zabbix 告警收敛(Python)研究价值高!

3303
来自专栏Laoqi's Linux运维专列

Kubernetes 1.8.6 集群部署–微服务持续集成→发布,拒绝停服(十五)

1624

扫描关注云+社区