【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)


想关注我吗?请点击图片上方【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)蓝字小麦苗关注即可,关注后您将可以每日获得最实用的数据库技术。请将小麦苗公众号置顶,小麦苗不喜欢被压着,~O(∩_∩)O~


小麦苗的今日寄语

     故天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。

【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)       

    各位粉丝朋友,从8月13日开始,小麦苗打算花很长很长的一段时间来给大家分享有关自己整理的等待事件的学习笔记,有的内容来自于网络,大家有什么问题可以留言,欢迎交流。

    今天给大家分享的是等待事件中的User I/O 类等待事件之direct path read(直接路径读),还是很重要的一个等待事件。

【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)等待事件历史文章

【等待事件】等待事件概述(1)--等待事件的源起和分类

●【等待事件】User I/O类 等待事件(2.1)--db file sequential read(数据文件顺序读)

【等待事件】User I/O类 等待事件(2.2)--db file scattered read(数据文件离散读)

【等待事件】User I/O类 等待事件(2.3)--db file parallel read

【等待事件】User I/O类 等待事件(2.4)--db file single write



【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)



直接路径读等待事件的3个参数分别是:file#(指绝对文件号)、first block#和block数量。

SELECT * FROM V$EVENT_NAME A WHERE A.NAME = 'direct path read';


【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR) 

这个等待事件有三个参数:

file number: 等待I/O读取请求的文件的绝对文件号

first dba: 等待I/O读取请求的第一个BLOCK号

block cnt: 以first block为起点,总共有多少个连续的BLOCK被请求读取

 

直接路径读(direct path read)通常发生在Oracle直接读取数据到PGA,这个读取不需要经过SGA。这类读取通常在以下情况被使用:

① 大量的磁盘排序IO操作,包括order by, group by, union, distinct, rollup, 无法在PGA中完成排序,需要利用temp表空间进行排序。 当从临时表空间中读取排序结果时,会产生direct path read,从10g开始表现为direct path read temp等待事件。

② 大量的Hash Join操作,利用temp表空间保存hash区。

③ SQL语句的并行处理,并行查询从属进程

④ 预读操作

⑤ 串行全表扫描(Serial  Table  Scan)大表的全表扫描,在Oracle11g中,全表扫描的算法有新的变化,根据表的大小、高速缓存的大小等信息,决定是否绕过SGA直接从磁盘读取数据。而10g则是全部通过高速缓存读取数据,称为table scan(large)。11g认为大表全表时使用直接路径读,可能比10g中的数据文件散列读(db file scattered reads)速度更快,使用的latch也更少。

最常见的是第一种情况。在DSS系统中,存在大量的Direct path read是很正常的,但是在OLTP系统中,通常显著的直接路径读都意味着系统应用存在问题,从而导致大量的磁盘排序读取操作。

db file sequential read、db file scattered read、direct path read是常见的集中数据读方式,下图简要描述了这3种方式的读取示意。


【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR) 

大量的direct path read等待时间最可能是一个应用程序问题。 

direct path read事件由SQL语句驱动,这些SQL语句执行来自临时的或常规的表空间的直接读取操作。当输入的内容大于PGA中的工作区域时,带有需要排序的函数的SQL语句将排序结果写入到临时表空间中, 临时表空间中的排序顺序串随后被合并,用于提供最终的结果。读取排序结果时, Oracle会话在direct path read等待事件上等待。

对于这一写入等待,我们应该找到I/O操作最为频繁的数据文件(如果有过多的排序操作,很有可能就是临时文件),分散负载,加快其写入操作。

DB_FILE_DIRECT_IO_COUNT初始化参数可能影响direct path read的性能。

串行全表扫描(Serial Table Scan)--Oracle 11g全表扫描以Direct Path Read方式执行


在Oracle 11g之前,全表扫描使用db file scattered read的方式,将表中的数据块离散的读到Buffer Cache之后,供用户访问和使用,但是如果全表访问的表非常大,则有可能占用大量的Buffer Cache内存,这会导致Buffer Cache中其他数据被老化和挤出内存,而且在这一系列的读取操作中,Oracle引擎需要去判断每一个数据块是否已经存在于内存中,然后还要去请求内存空间,不断使用Cache Buffer Chain和Cache Buffer Lru Chain两个Latch进行判断,在某种程度上会加剧Latch竞争,如果全表访问的数据只是偶尔个别的访问,则占据大量Buffer  Cache就显得过于昂贵,在Oracle Database 11g中,一种被称为串行全表扫描(Serial  Table  Scan)的技术被引入,该特性根据数据块的设置和统计信息等,自动决定是采用Direct Path Read绕过SGA,还是采用常规方式读取,因为这种自动选择,这一特性又被称为自适应直接读(Adaptive  Direct Read).这种方式的好处是可以降低Buffer Cache的竞争,但是每次都要发生物理读,若是有多个会话同时去扫描同一张大表,这样会增大IO,也有可能导致系统的问题,而且在读取之前可能需要触发检查点,避免读到旧的映像。

在Oracle Database 11g中有一个新特性,全表扫描可以通过直接路径读的方式来执行(Direct Path Read),这是一个合理的变化,如果全表扫描的大量数据读取是偶发性的,则直接路径读可以避免大量数据对于Buffer Cache的冲击。

当然对于小表来说,Oracle允许通过Buffer Cache来进行全表扫描,因为这可能更快,也对性能影响不大。小表受到隐含参数:_small_table_threshold 影响。如果表大于 5 倍的小表限制,则自动会使用DPR替代FTS。可以设置初始化参数: _serial_direct_read 来禁用串行直接路径读。

当然,Oracle通过一个内部的限制,来决定执行DPR的阈值。

可以通过设置10949事件屏蔽这个特性,返回到Oracle 11g之前的模式上:

altersession setevents '10949 trace name context forever, level 1';

还有一个参数 _very_large_object_threshold 用于设定(MB单位)使用DPR方式的上限,这个参数需要结合10949事件共同发挥作用。10949 事件设置任何一个级别都将禁用DPR的方式执行FTS,但是仅限于小于 5 倍 BUFFER Cache的数据表,同时,如果一个表的大小大于 0.8 倍的 _very_large_object_threshold  设置,也会执行DPR。

这些限定的目标在于:

对于大表的全表扫描,必须通过Direct Path Read方式执行,以减少对于Buffer Cache的冲击和性能影响。但是我们可以通过参数调整来决定执行DPR的上限和下限。

Oracle通过隐含参数_small_table_threshold来界定大表小表的临界,Oracle认为对于大表执行直接路径读取的意义比较大,对于小表通过将其缓存可能受益更大。_small_table_threshold的单位为block。默认为db cache size的2%大小,在实例启动过程中动态决定。11GR2之前,表的大小要是_small_table_threshold参数值的5倍才会采取直接路径读取方式,11GR2后只需要满足_small_table_threshold定义的大小就会采取直接路径读取。

 

在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了。 在10g中,都是通过gc buffer来读的,所以不存在direct path read的问题。

一个隐含参数_serial_direct_read可以禁用串行直接路径读,11g默认值为auto:

禁用direct path read:  _serial_direct_read = false

启用direct path read:  _serial_direct_read = true  

alter sytem set "_serial_direct_read"=never scope=both sid='*'; 可以显着减少direct path read

调整数据库参数alter system setevent='10949 trace name context forever, level 1'来关闭“direct path read”(直接路径读)特性,使SQL语句可以从缓存中查询数据,达到降低I/O读取量,使全表扫描的数据从缓存中读取,加快SQL语句运行速度的目的。



场景:关于直接路径读的一个案例处理

Oracle 11g新特性direct path read引发的系统停运故障诊断处理 http://blog.itpub.net/26736162/viewspace-2123524/

深入分析direct path read(11G) - Oracle数据库管理 - ITPUB论坛-中国最专业的IT技术社区 http://www.itpub.net/thread-1815281-1-1.html


【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)



About Me:小麦苗●李华荣      

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新,推荐pdf文件阅读或博客园地址阅读

● QQ群:230161599  微信群:私聊

● 小麦苗分享的其它资料:http://blog.itpub.net/26736162/viewspace-1624453/

●  联系我请加QQ好友(642808185),注明添加缘由

●【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】



长按识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。

【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)

【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)


【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)


【等待事件】User I/O类 等待事件(2.5)--direct path read(直接路径读、DPR)



本文分享自微信公众号 - DB宝(lhrdba)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

上一篇:lib-flexible适配大屏方案


下一篇:uniapp微信小程序 使用canvas 绘制波浪线