1.等待事件分类
根据OWI(Oracle Wait Interface)定义来看,Oracle等待事件主要分为以下几类:
1.IO Wait Event
2.Lock/Latch Event
3.Latency Wait Event
4.RAC Wait Event
主要涉及几个查询视图:
V$SESSION_WAIT
V$SYSTEM_EVENT
V$EVENT_NAME
以上视图构成了OWI基本的查询基础。
2.IO如何产生
1.IO如何产生,且先看下面一张图:
PS:多年前画的,有点粗糙,不过还能用吧。
1)Physical I/O产生:当搜索内存Hash chains没有找到合适的buffer,则必须从disk磁盘读取该block到buffer;
2)获取CBC(cache buffer chain latch) latch;
3)drop latch(cache buffer chain latch),将block读入buffer cache,对其他user透明操作;
4)在其他user也访问该block的并发场景,加载block到buffer过程:
-
从REPL_AUX中获取一个free的Buffer Header;
-
在该Buffer Header加上Block Address(rdba)标记;
-
将组装的好的BH链接到正确的Cache Buffer Chain上;
-
同时注入Pin(X),使得其他user可以读取,但是不能物理更改(DML);
-
释放latch,同时将block加载load进Buffer Cache。
2.CacheBuffer Chain(Latch)结构:
3.Cache Buffer Pin与参数"_db_block_max_cr_dba"
当需要对Buffer Block内容进行更改时,必须使用Cache Buffer Pin进行保护。如果这时对该Buffer Block进行查询,那么系统就会以当前Pin 住的Buffer Block为基础块,重构CR镜像。
参数_db_block_max_cr_dba参数限定了单个Block Buffer的最大CR镜像数量,同时从侧面限制了Chains的长度,提高了Chains扫描的速度,默认为6:
4.“Buffer Busy Wait”
Cache Buffer Pin结构中包含了Pin相关的信息,当被阻塞的会话没有请求到Pin时,就可以将自己地址信息等提交到Wait list的末端进行等待,等待事件为“buffer busy wait”, 由参数_buffer_busy_wait_timeout决定,默认为1秒钟:
3.令部分人"谈虎色变的Direct IO"
先前在某群有看到有个因为Direct IO导致故障的Case,貌似折腾了很久,当事人也似乎对于Direct IO有点“谈虎色变”了,借此机会浅析一下。
1.Direct IO:
用户Session PGA中读/写数据,直接到磁盘读取/落盘,而不经过SGA(Buffer Cache),从而减少大批量读取/写入数据对BufferCache的性能冲击,提升IO性能。Direct IO可以通过设置DISK_ASYNC_IO是否同步或者异步模式,默认异步模式。
2.Direct IO主要场景:
Direct IO主要由排序引起的,例如group by/union/distinct/rollup/LOB大对象,以及当排序数据超过PGA(work_area)时,在merge join或者load data 使用hint(append)等场景。
3.Direct IO如何优化:
-
减少不必要排序
-
创建合适的索引
-
根据索引有序性调整组合索引列索引方式,减少索引排序大小
-
设置较大的DB_FILE_DIRECT_IO_COUNT和DB_BLOCK_SIZE,提升IO吞吐性能
-
增加PGA_AGGREGATE_TARGET到合适值
-
使用UNION ALL改写UNION
-
使用HASH JOIN代替SORT MERGE
-
使用NESTED LOOPS代替HASH JOIN
-
确保优化器使用正确的驱动表
由于篇幅有限,Oracle等待事件就介绍到这,关于其他维度的等待事件后续有机会再分享。
PS打个小广告,准备了一些深入学习Oracle的资料以及配套录制视频(知识星球),有兴趣的同学请联系微信号或者知识星球:dba悠然同行成长圈(见附录二维码)。
如果觉得本文有所帮助或者启发,欢迎添加好友交流收藏(篇幅有限,更多资讯请关注附录知识星球二维码),2024年我们一路同行!!!。