Oracle数据库管理-direct path /direct path write

(1)概念

 传统读取数据的方式是服务器进程通过读取磁盘,然后把数据加载到共享内存中,这样后面的进程就可以通过共享内存访问这些数据,不用再通过缓慢的磁盘读取来 完成。direct path read读取数据块方式,是指服务器进程直接读取数据文件,

不经过buffer cache,这种方式读取的数据块会加载到服务器进程的PGA内中当中,不会进入buffer cache中。 

11G 之 前的direct path read主要用于并行查询中,此等待事件的三个参数p1,p2,p3分别代表:file#:文件号,first block#:读取的起始块号,block count:以first block为起点,

连续读取的物理块数。而从11G之后,direct path read不仅可用于并行查询,在符合某些条件后,串行的全表扫描也可以利用direct path read方式来完成。这里主要介绍11G direct path read相关的特性。

direct path read 参数说明:
事件号:212
事件名:direct path read
参数一:读取数据文件的绝对文件号码file number
参数二:起始块号first dba
参数三:要读取的块数block cnt
由参数P1与P2推得访问的数据对象:
select s.segment_name, s.partition_name from dba_extents s where <P2的值> between s.block_id and (s.block_id + s.blocks -1) and s.file_id = <P1的值>

上面的12个块为一个extent,假设都不在buffer cache中的话,一次物理IO就可以完成,但是由于部分块被cache,而导致总共需要6次的物理IO才行。

因此在做全表扫描的情况下,表里的数据一部 分被cache并不见得总是好事。当时我在想,如果可以绕过buffer cache,直接路径读取就好了。

11G以后,ORACLE终于推出了这个功能,在全表扫描的时候,如果ORACLE认为这个表足够大,就会启用直接路径读取,而不需要像11G之前,必须先把数据加载到buffer cache

(2)产生原因

1、索引online重建过程,产生大量的 direct path read/write temp以及direct path write等待。

2 、online创建索引也会产生。

3 、CTS也是直接路径。

4、在排序操作(order by/group by/union/distinct/rollup/合并连接)时,由于PGA中的SORT_AREA_SIZE空间不足,造成需要使用临时表空间来保存中间结果,当从临时表空间读入排序结果时,产生direct path read等待事件。

5、使用HASH连接的SQL语句,将不适合位于内存中的散列分区刷新到临时表空间中。为了查明匹配SQL谓词的行,临时表空间中的散列分区被读回到内存中(目的是为了查明匹配SQL谓词的行),ORALCE会话在direct path read等待事件上等待。

6、使用并行扫描的SQL语句也会影响系统范围的direct path read等待事件。在并行执行过程中,direct path read等待事件与从属查询有关,而与父查询无关,运行父查询的会话基本上会在PX Deq:Execute Reply上等待,从属查询会产生direct path read等待事件。

7、11G版本 新特性直接路径代替全表扫描。

8、alter table table_name move parallel 10,也产生大量的direct path write操作,

(3) 产生阀值

1)表大于_small_table_threshold的参数值设置      

     Oracle通过隐含参数_small_table_threshold来界定大表小表的临界,Oracle认为对于大表执行直接路径读取的意义比较大, 对于小表通过将其缓存可能受益更大。_small_table_threshold的单位为block。

默认为db cache size的2%大小,在实例启动过程中动态决定。11GR2之前,表的大小要是_small_table_threshold参数值的5倍才会采取直接路 径读取方式,11GR2后只需要满足_small_table_threshold定义的大小就会采取直接路径读取。

2)表上的脏块小于表总block数的25%(脏块的比例大约达到表块的25%(共3000个表块)的时候,直接路径读消失了)

3)表中的块被cache的比例小于50%的时候(在接近50%(共3000个表块)的表块被cache的时候,直接路径读消失了。)

总结表格如下:

满足以上条件时,Oracle会进行直接路径读取。

Oracle为直接路径读取设置的三个“门槛”,非常的合理:

第 一个阀值:表大小,太小的表从direct path read中的获益太小。但是特别需要引起你的警惕,如果表上存在统计信息,那么ORACLE会采取表的统计信息中记录的block与 _small_table_threshold的设定值来做比较,而不是表的真实大小(dba_segments中记录的值)。这可能导致一些不是你预期 的情况发生。如果你的统计信息与表的真实情况差异很大,那么你应该仔细考虑可能发生什么样的结果。如果你的表没有统计信息,ORACLE会依据表的真实大 小来决定是否进行direct path read。

第二个阀值:脏块阀值,由于direct path read需要出发一个段的检查点,因此脏块太多,刷新脏块可能会导致IO繁忙

第 三个阀值:表在内存里的cache率,如果cache率很高,那么还是走传统路径更快。direct path read的出现,需要让ORACLE公司的开发人员设计一个单独的结构来存储每个表有多少数据是脏数据,有多少数据被cache。不过这个结构目前还并未 暴露给我们查询。在flush buffer cache后,这个结构被清空。(flush shared_pool并不会被清空)

当你预期一个查询应该会走direct path read,但是却走了传统的路径扫描的时候,应该检查是否违背了这三个前置条件中的一个或几个。不过很多时候,当一个查询“应该”走direct path read但是却没有的时候,你往往无能为力,你能在数据库运行过程中修改表的数据的cache比例吗?不能!你能修改表的脏数据的比例吗?往往也不能,通 过修改表的统计信息中的表块数,可以满足第一个条件,但是如果不满足其他两个条件,依然不能有效。你可以通过flush buffer cache来满足后两个条件,但往往在生产环境中不被允许。我曾经在个人微博(新浪微博:魏兴华-DBA)发布过一个关于索引创建走不上direct path read的微博,现在终于想明白了,不满足第三个条件,表被cache的内容需要低于50%。

(4)direct path read的优势

  •  采用直接路径读取后,总能保证读取的块数是多块读参数设置的大小,提高了读取的效率
  • 大大的降低了对于latch的使用,进而避免了可能导致的latch竞争(cbc latch等)
  • 降低了全表扫描对buffer cache的冲击
  • 降低了buffer pin的开销,有可能降低buffer busy waits等相关等待

(5)direct path read的缺点

  • 会发生段一级的检查点,因此在查询真正开始执行前,会做这个额外的准备工作。而且可能会造成IO抖动,因为要写脏数据。
  • 如果你的表需要频繁的全表扫描读取,还是用传统的读取方式比较好。
  • 在MOS中搜索direct path read,会发现它可能会导致多次的延迟块清除。
  • 在以往的案例中,产生大量的IO,导致IO瓶颈。
  • 大量的IO调度到底sys% cpu部分消耗较大,将cpu吃满。

(5.1) 直接路径读为什么要发生检查点

1)直接路径读取如果有必要,也会去构造CR块,不过这里的CR块是在PGA中构造的,而不是在buffer cache中构造的。
2)如果表上没有任何的脏数据,并不会触发段上的检查点,这一点也很容易用10046跟踪出来,因此如果你想通过10046跟踪到段检查点,需要保证这个表上在内存中有脏数据。

(5.2) 延迟块清除与直接路径读

由于直接路径读取是发生在进程的PGA中的,如果读取过程中,ORACLE发现一些块没有做块清除,会在PGA中进行延迟 块清除的操作,但是这个清除的操作并不会记录日志,且被清除过的块并不会被刷回到磁盘。正是由于延迟清除过的块不被写回到磁盘,因此如果有比较多的进程来 进行直接路径读取,就会导致各个进程反复的进行块清除的操作,一定程度上浪费了CPU资源

(6)控制direct path read

可以采用ALTER session/system SET EVENTS '10949 TRACE NAME CONTEXT FOREVER';来禁用direct path read。

可以通过alter session/system set "_serial_direct_read"=false;;来禁用direct path read。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值