一.什么是buffer busy waits

当n个进程想以不兼容的模式持有内存块上的buffer pin时,就会产生buffer busy waits等待。

oracle访问/修改数据块的步骤:

1.依据数据块的地址计算出数据块所在的bucket

2.获得保护这个bucket的cbc latch

3.在这个链表上查找需要的数据块,找到后,pin这个buffer(读取s,修改x)

4.释放cbc latch

5.读取/修改数据块的内容

6.获取cbc latch

7.unpin这个buffer

8.释放cbc latch

分析:因为latch的操作都是很短的,上面步骤中除了步骤5,都可以认为是极快的操作。在大并发环境中,如果cbc latch的持有时间过长,会导致大量的latch争用,以致非常容易导致系统的cpu资源出现瓶颈。注意即使所有的操作都是查询非修改,也会导致大量的cbc latch争用:因为cbc latch的持有到cbc latch的释放这段时间太长了。oracle使用在内存块上加buffer pin的方式来解决这个问题。可以看出,这种实现方式使得cbc latch持有期间只做了很少的事情,大大降低了cbc latch的争用。

如果数据库里面读多写少,由于各个读之间的buffer pin时兼容的,都是s模式,因此几乎不会产生任何的争用。

如果数据库里面写多读少,就会产生buffer busy waits等待,但这种等待的代价比cbc latch的等待代价要小的多,因为latch的spin机制是非常耗cpu的,而buffer pin的管理本质上类似于enquen锁的机制,没有spin机制,不需要自旋转消耗大量的cpu。

二.buffer busy waits测试

创建测试表:

SQL> create table test_buffer_busy as select * from dba_objects;Table created.SQL> create index idx_test_buffer_1 on test_buffer_busy(object_id);Index created.

找到同一个块上的两条记录:

SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid) fn,dbms_rowid.rowid_block_number(rowid) bl, test_buffer_busy.object_id,rowid from test_buffer_busy where rownum<3;FN         BL  OBJECT_ID ROWID
---------- ---------- ---------- ------------------4       3131         20 AAAVXOAAEAAAAw7AAA4       3131         46 AAAVXOAAEAAAAw7AAB

1.场景1,读读操作

session1执行:

SQL> select sid from v$mystat where rownum=1;SID
----------1
SQL> declare2  c number;3  begin4  for i in 1 ..6000000 loop5  select count(*) into c from test_buffer_busy where rowid='AAAVXOAAEAAAAw7AAA';6  end loop;7  end;8  /

session2执行:

SQL> select sid from v$mystat where rownum=1;SID
----------37
SQL> declare2  c number;3  begin4  for i in 1 ..6000000 loop5  select count(*) into c from test_buffer_busy where rowid='AAAVXOAAEAAAAw7AAB';6  end loop;7  end;8  /

sesson3观察是否产生buffer busy waits等待事件:

SQL> select event,sid,p1,p2,p3 from v$session_wait where sid in (1,37) and event like '%buffer%';no rows selected

结论:读读场景不会产生任何buffer busy waits等待事件

2.场景2,写写操作

session1:

SQL> begin
for i in 1 ..40000000 loop2    3  UPDATE test_buffer_busy SET object_name=20 where rowid='AAAVXOAAEAAAAw7AAA';4  commit;5  end loop;6  end;7  /

session2:

SQL> begin2  for i in 1 ..40000000 loop3  UPDATE  test_buffer_busy SET object_name=46 where rowid='AAAVXOAAEAAAAw7AAB';4  commit;5  end loop;6  end;7  /

session3:

SQL> select event,sid,p1,p2,p3 from v$session_wait where sid in(46,50) and event like '%buffer%';no rows selected
EVENT                                                                   SID
---------------------------------------------------------------- ----------P1         P2         P3
---------- ---------- ----------
buffer busy waits                                                        464       3131          1buffer busy waits                                                        504       3131          1

参数解释:

p1:数据块驻留的绝对文件号。select file_name,relative_fno from dba_data_files;

p2:进程需要访问的实际数据块号。

p3:块类型编号

1  Data block2  Sort block3  Save undo block4  Segment header5  Save undo header6  Free List7  Extent map8  1st level bitmap block9  2nd level bitmap block10 3rd levelbitmap block11 Bitmapblock12 Bitmapindex block13 Fileheader block14 Unused15 Systemundo block16 Systemundo block17 Undoheader18 Undoblock

查看v$waitstat视图:

SQL> select * from v$waitstat;CLASS                   COUNT       TIME
------------------ ---------- ----------
data block              10349       2399

可以看到data block上面发生了大量等待。

两个session的等待里都有大量的buffer busy waits等待,由于session1和session2在同一个buffer上加x排他的buffer pin,两种锁模式的不兼容导致了争用。

3.场景3,读写操作

session1:

SQL> begin2  for i in 1..40000000 loop3  UPDATE test_buffer_busy SET object_name=20 where rowid='AAAVXOAAEAAAAw7AAA';4  commit;5  end loop;6  end;7  /

session2:

SQL> declare2  c number;3  begin4  for i in 1..6000000 loop5  select count(*)into c from test_buffer_busy where rowid='AAAVXOAAEAAAAw7AAB';6  end loop;7  end;8  /

session3:

SQL> select event,sid,p1,p2,p3 from v$session_wait where sid in (1,37) and event like '%buffer%';EVENT                                                                   SID
---------------------------------------------------------------- ----------P1         P2         P3
---------- ---------- ----------
latch: cache buffers chains                                               1
2362473448        177          0buffer busy waits                                                        373        272         35

可以看到,session1没有任何的buffer busy waits等待,而进行读操作的session2,产生了大量的buffer busy waits等待。原理:

(1).当读取的进程发现内存块正在被修改时(x模式的buffer pin),它只能等待而不能clone,因为这个时候内存块正在变化过程中,这个时候clone是不安全的。这个时候,读的进程只能等待buffer busy waits。

(2).当写的进程发现内存块正在被读,这个时候,读时不阻塞写的,因为oracle可以很容易的clone出一个数据块,然后在clone的块上进行写,这个时候clone是安全的,因为读内存块的进程不会去修改数据块,保证了clone的安全性。

三.总结

1.buffer busy waits是产生在buffer block上的等待,由于n个进程想以不兼容的模式获得buffer block上的buffer pin时,进而引起buffer waits等待。

2.buffer block的管理模式类似enq锁,先进先出,由队列记录锁的拥有者和等待者

3.写写,读写操作都会产生buffer busy waits等待。写写的两个会话,都会产生buffer waits等待,而读写的两个会话,只有读的session会产生,因为它不能简单的clone一个数据块,正在发生写的内存块发生clone是不安全的。

4.oracle为了减少cbc latch持有时间过长的问题,以每次访问buffer block的会话获取两次cbc latch,再配合在内存块上加buffer pin来解决这个问题。

buffer busy waits理解相关推荐

  1. buffer busy waits等待事件案例-vage

    讨厌香草冰激凌的汽车与Buffer busy wiats的故事 记得好几年前看到过一个故事,通用公司曾收到一客户的邮件,邮件中客户描述了一个非常奇怪的问题.他们家有晚饭后去吃冰激凌的习惯,如果他们买的 ...

  2. buffer busy waits等待事件的原因:hot block [转]

    http://blog.chinaunix.net/u/24260/showart_456274.html ********************************************** ...

  3. 前台等待事件 oracle,Oracle等待事件之buffer busy waits

    产生原因 官方定义: This wait happens when a session wants to access a database block in the buffer cache but ...

  4. latch: cache buffers chains 阻塞 buffer busy waits

    os: centos 7.4 db: oracle 11.2.0.4 版本 # cat /etc/centos-release CentOS Linux release 7.4.1708 (Core) ...

  5. buffer busy waits

    当进程需要存取SGA中的buffer的时候,它会依次执行如下步骤的操作: 1.获得cache buffers chains latch,遍历那条buffer chain直到找到需要的buffer he ...

  6. Oracle等待事件(三)—— buffer busy waits 常见原因及对应解决方法

    也先看看buffer busy waits在官方文档中的描述 This wait indicates that there are some buffers in the buffer cache t ...

  7. 等待事件buffer busy waits

    转载自:http://blog.csdn.net/cymm_liu/article/details/7968537 非空闲等待之:buffer busy waits buffer busy wait ...

  8. Buffer Busy Waits的两个结论

    官方文档: This wait indicates that there are some buffers in the buffer cache that multiple processes ar ...

  9. oracle+buffer+busy+wait,Oracle数据库buffer busy wait等待事件 (2)

    --查找等待块类型 SELECT 'segment Header' CLASS, a.Segment_Type, a.Segment_Name, a.Partition_Name FROM Dba_S ...

最新文章

  1. OC 组合实现多继承
  2. 《javascript设计模式》笔记之第十章 和 第十一章:门面模式和适配器模式
  3. device:GPU:0 but available devices are [ /job:localhost/replica:0/task:0/dev
  4. 智能合约重构社会契约 (5)比特犬模型实现智能合约
  5. 【MM模块】 Info Record 采购信息记录
  6. linux为什么开机后有多个内核,CentOS7开机界面出现多个内核选项
  7. 3.注释(代码的整洁之道)
  8. app上线发布流程_APP上线发布流程
  9. 一步步编写操作系统 26 打开A20地址线
  10. IIS错误信息--另一个程序正在使用此文件,进程无法访问!
  11. 为什么有时不能正确定位到异常的发生位置?
  12. Java酒店管理系统项目
  13. python创建一个银行账户类account_银行账户(示例代码)
  14. CAShapeLayer把图片做成圆形效果
  15. php mp3播放列表,ubuntu的本地MP3音乐播放器mpd+mpc
  16. (十)DSP28335基础教程——ECAP实验(超声波测距)
  17. 【算法】深度搜索(DFS) 和 广度搜索(BFS)
  18. google maps js v3 api教程(3) -- 创建infowindow
  19. PHP + elasticsearch的使用方法,PHP使用ES的超级简单方法
  20. 今天是国际数学日,既是爱因斯坦的生日又是霍金的忌日

热门文章

  1. 小程序---搜索框实现
  2. 【大熊智能nrf connect使用方法
  3. 每个程序员都应该读的数学书
  4. 辰视智能董事长冯良炳博士接受深圳广电集团众创TV专访
  5. asp.net 文件操作
  6. Oracle:子查询——rownum
  7. 基于物联网的室内环境检测云系统设计(树莓派RPI、Arduino、智能家居、RFID、APP)
  8. mysql在线考试的设计_在线考试系统设计与实现(MySQL)
  9. SPM——Spatial Pyramid Matching
  10. RRT(Rapidly-exploring Randomized Trees)算法学习笔记