楼主: vage

[精华] 讨厌香草冰激凌的汽车与Buffer busy wiats的故事

[复制链接]
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:24:51
41#
发表于 2012-3-2 10:47 | 只看该作者
好文好文

使用道具 举报

回复
论坛徽章:
70
夏利
日期:2013-09-29 21:02:15天蝎座
日期:2016-03-08 22:25:51嫦娥
日期:2014-03-04 16:46:45ITPUB年度最佳技术原创精华奖
日期:2014-03-04 16:19:29马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:11
42#
 楼主| 发表于 2012-3-2 14:00 | 只看该作者
sunyunyi 发表于 2012-3-2 10:06
buffer busy waits 由两种情况引起,1:需要被访问的数据块正在被读入内存 2:buffer lock 存在不兼容模式。 ...

有一点可能是没说清楚,没有发现DML,并不等于没有DML。
这涉及到buffer busy waits的另外一个问题,也就是你所提到的第二点:

2:buffer lock 存在不兼容模式。

此处的不兼容模式,如果只理解为读、写(也就是共享与独占),或是写、写(独占与独占)之间的不兼容,就太简单了点。这已经是多年前无数前辈已经验证的观念了。但,是多年前。
Oracle在进步,9i, 10g, 11g, 12c(还不确定),这么多年来,这么多版本下来,Oracle内部的改动,已经不是一点半点。你看Larry Ellision像是吃老本的人吗。拿以前的理论,来推论现在的问题,是有点危险的。其实软件的进步,我们不能只学习操作层面的东西,内核的变动才是关键。

比如这个Buffer busy waits,在10G以后的版本做个测试便知。
比如在会话1运行如下脚本:
declare
   j number;
begin
for i in 1..3000000 loop
   select id into j from a1 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
end;
/

反复读取某一行。
在会话2如下脚本:
begin
for i in 1..300 loop
   update a1 set id=id+0 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
commit;
end;
/

然后在V$SESSION_EVENT中查看两个Session的Buffer busy waits等待。

会话1反复查询一行,会话2反复更新同一行300次,两个会话应该各有少许的Buffer busy waits,对吧。
但实际情况不是这样的。会话2一般不会有,只有会话1会有Buffer busy wait等待。

Buffer Lock(内存的锁,称为Pin更合适,很多老外也是这么称乎的,我在下面称其为Buffer pin)的兼容模式为:
1、写、写互相阻塞。
2、写 阻塞 读。
3、读 不阻塞 写。

另外,在做上面的测试,偶而也会有写被读阻塞,而产生的Buffer busy wait,但这个很少见。这是由于IMU机制产生的影响。我会在后面的文章中,详细讨论。不过,可能会有点太深入,需要一些基础才能阅读。

使用道具 举报

回复
论坛徽章:
21
娜美
日期:2017-06-26 15:18:15火眼金睛
日期:2018-04-30 22:00:00目光如炬
日期:2018-07-29 22:00:00火眼金睛
日期:2018-08-31 22:00:00目光如炬
日期:2018-09-02 22:00:00目光如炬
日期:2018-09-16 22:00:01火眼金睛
日期:2018-09-30 22:00:00目光如炬
日期:2018-10-14 22:00:00火眼金睛
日期:2018-11-30 22:00:01目光如炬
日期:2018-04-29 22:00:00
43#
发表于 2012-3-2 15:49 | 只看该作者
3、读 不阻塞 写.
buffer lock 只有s 和x 模式,s---s 兼容,其他三种都是不兼容的,读也是会阻塞写的。
只要出现buffer lock不兼容模式就可能出现 buffer busy wait 事件。
我是这样理解的,不知道对不?

使用道具 举报

回复
论坛徽章:
70
夏利
日期:2013-09-29 21:02:15天蝎座
日期:2016-03-08 22:25:51嫦娥
日期:2014-03-04 16:46:45ITPUB年度最佳技术原创精华奖
日期:2014-03-04 16:19:29马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:11
44#
 楼主| 发表于 2012-3-2 22:21 | 只看该作者
sunyunyi 发表于 2012-3-2 15:49
3、读 不阻塞 写.
buffer lock 只有s 和x 模式,s---s 兼容,其他三种都是不兼容的,读也是会阻塞写的。
...

10G后,在已经使用IMU的情况下,已经不是这样的了,写会阻塞读,但读不会阻塞写。
所以,如果有DML和Select操作同一块,只会看到Select有Buffer busy waits等待。
我后面会整理详细的验证此点的测试步骤

使用道具 举报

回复
论坛徽章:
21
娜美
日期:2017-06-26 15:18:15火眼金睛
日期:2018-04-30 22:00:00目光如炬
日期:2018-07-29 22:00:00火眼金睛
日期:2018-08-31 22:00:00目光如炬
日期:2018-09-02 22:00:00目光如炬
日期:2018-09-16 22:00:01火眼金睛
日期:2018-09-30 22:00:00目光如炬
日期:2018-10-14 22:00:00火眼金睛
日期:2018-11-30 22:00:01目光如炬
日期:2018-04-29 22:00:00
45#
发表于 2012-3-3 22:02 | 只看该作者
我们看一下oracle 官方资料
Buffer Modes:
KCBMNEW        : New buffer for exclusive access
KCBMSHR                : Current buffer for shared access
KCBMEXL                : Current buffer for exclusive access
KCBMCR                : CR buffer for shared access
KCBMCRX                : Variant of CR mode
KCBMNULL        : Used to keep a reference to the buffer
Mode Compatibilities:
                              requested mode
                      new   shr  exl  cr  crx   null
held      null     y        y    y     y      y     y
             shr      n      y     n     y     y      n
             exl      n     n     n      n     n      n
         
Getting Current Buffers
Searching for current buffers:
Scan the hash chain to which the RDBA maps.
For each buffer in the chain:
Ignore buffers that do not match RDBA
Wait for READING buffer and return them
Skip CR (consistent read) buffers
If the CUR (current) buffer is held in a compatible mode, then use it
Otherwise if all other users are CR state objects
                – Make it a CR copy and create a new EXLCUR copy of the buffer
                – Or wait for the current buffer to be released
If no usable buffers exist in cache, read from disk
Attach a state object to the buffer header
Return pointer to data area
Buffer busy waits
The buffer we want is either being read into the buffer cache by another process, or it is in an incompatible mode and is being modified. Normally the wait time is one second, except in the case if this is the second wait for an exclusive block, in which case the wait is three seconds. This event is the indication for data block contention, the same buffer is requested by more than one process at any given time. Reducing waits on this event depends on the block type (data, segment header, undo).

buffer busy wait  和 IMU 没有什么关系,IMU只是在 imu commit 时批量提REDO。

使用道具 举报

回复
论坛徽章:
70
夏利
日期:2013-09-29 21:02:15天蝎座
日期:2016-03-08 22:25:51嫦娥
日期:2014-03-04 16:46:45ITPUB年度最佳技术原创精华奖
日期:2014-03-04 16:19:29马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:11
46#
 楼主| 发表于 2012-3-4 12:56 | 只看该作者
declare
    j number;
begin
for i in 1..3000000 loop
    select id into j from a1 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
end;
/

反复读取某一行。
在会话2如下脚本:
begin
for i in 1..300 loop
    update a1 set id=id+0 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
commit;
end;
/
用这两个存储过程,反复访问同一块。在IMU下和非IMU下区别是非常明显的。
非IMU下,Select和Update都有Buffer busy waits,在IMU下,Update下就没有(也有可能只有少量,但原因是没有使用成IMU)Buffer busy waits。
可以试一下。

引入IMU对数据库的改变还是很大的,不仅仅只是imu commit 时批量提REDO 。 也不仅仅是将UNDO信息放入共享池。对Buffer Busy Waits影响就是一例。你可以测一下。

使用道具 举报

回复
论坛徽章:
57
SQL极客
日期:2013-12-09 14:13:35秀才
日期:2016-01-21 13:42:39秀才
日期:2016-01-13 12:14:26SQL大赛参与纪念
日期:2016-01-13 10:32:19SQL数据库编程大师
日期:2016-01-13 10:30:43秀才
日期:2015-12-14 14:47:54秀才
日期:2015-10-19 15:50:392015年新春福章
日期:2015-03-06 11:58:18懒羊羊
日期:2015-03-04 14:52:11优秀写手
日期:2014-11-08 06:00:14
47#
发表于 2012-3-4 17:17 | 只看该作者
好文,支持原创。

使用道具 举报

回复
论坛徽章:
51
ITPUB十周年纪念徽章
日期:2011-11-01 16:25:22铁扇公主
日期:2012-02-21 15:03:13最佳人气徽章
日期:2012-03-13 17:39:18ITPUB季度 技术新星
日期:2012-05-22 15:10:11ITPUB 11周年纪念徽章
日期:2012-10-09 18:13:332013年新春福章
日期:2013-02-25 14:51:24ITPUB社区12周年站庆徽章
日期:2013-08-12 09:34:36itpub13周年纪念徽章
日期:2014-09-28 10:55:55
48#
发表于 2012-3-5 14:02 | 只看该作者
这个还是有道理的
小transaction在内存里完成读写,比在从UNDO SEGMENT里读写入的速度要快
所以减少buffer busy
很多东西还是得深入学习啊~好贴

使用道具 举报

回复
论坛徽章:
14
奥运会纪念徽章:拳击
日期:2008-04-24 10:00:15CTO参与奖
日期:2009-02-12 11:45:482012新春纪念徽章
日期:2012-02-07 09:59:35ITPUB季度 技术新星
日期:2012-02-16 14:53:16鲜花蛋
日期:2012-03-19 18:10:462013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11
49#
发表于 2012-3-5 14:32 | 只看该作者
对待技术要有这种刨根究底的精神

使用道具 举报

回复
论坛徽章:
21
娜美
日期:2017-06-26 15:18:15火眼金睛
日期:2018-04-30 22:00:00目光如炬
日期:2018-07-29 22:00:00火眼金睛
日期:2018-08-31 22:00:00目光如炬
日期:2018-09-02 22:00:00目光如炬
日期:2018-09-16 22:00:01火眼金睛
日期:2018-09-30 22:00:00目光如炬
日期:2018-10-14 22:00:00火眼金睛
日期:2018-11-30 22:00:01目光如炬
日期:2018-04-29 22:00:00
50#
发表于 2012-3-6 08:33 | 只看该作者
小transaction在内存里完成读写,比在从UNDO SEGMENT里读写入的速度要快
所以减少buffer busy,这是减少 buffer busy 的真正原因,提高了CR块的访问效率。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表