暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

db file scattered read

原创 逆风飞翔 2022-07-21
396

oracle在执行全表扫描(Full Table Scan,FTS)或全索引扫描(Index Full San)时,为保障性能,尽量一次读取多个块,这称为Multi Block I/O。每次执行Multi Block I/O,都会等待物理I/O结束,此时等待db file scattered read事件。

SQL> select event#,name,parameter1,parameter2,parameter3 from v$event_name where name = 'db file scattered read';

select name,parameter1,parameter2,parameter3,wait_class from v$event_name where name = 'db file scattered read';

file#:要读取的数据块锁在数据文件的文件号。
 block#:要读取的起始数据块号。
 blocks:要读取的数据块数目。

当会话发出一个读入多个数据块的I/O请求时提交db file scattered read(数据文件离散读取)等待事件
db file scattered read等待事件发生的原因 :
 1.全表扫描
 2.索引快速全扫描

解决:
1.平均等待时间不应该超过20ms, 否则证明存储存在争用。
 2.OLTP系统应避免出现此等待事件。
 3.优化方式:加大SGA, 避免全表扫描,提高存储性能,对频繁访问的做cache等。
 4.调高数据库参数: db_file_multiblock_read_count可降低等待次数,但大于1MB/blocks_size无效。

SQL> alter session set events '10046 trace name context forever, level 12'; -- 启用跟踪
SQL> alter session set events '10046 trace name context off'; --停止跟踪


---特定session 开启10046跟踪
在另外的session中对当前session进行10046追踪:
 SQL> oradebug setospid 9305
 Oracle pid: 22, Unix process pid: 9305, image: oracle@zhuga (TNS V1-V3)
 SQL> oradebug event 10046 trace name context forever,level 12
 Statement processed.
 SQL> oradebug tracefile_name
 /opt/app/oracle/diag/rdbms/bddev2/BDDEV2/trace/BDDEV2_ora_9305.trc
对测试表进行操作,持续观察追踪文件的输出。


设置追踪标识符
alter session set tracefile_identifier='10046';
开启跟踪
alter session set events '10046 trace name context forever, level 12';
执行语句
select count(*) from all_objects;
关闭10046追踪
alter session set events '10046 trace name context off';
当退出当前会话的时候,Oracle就会将追踪的结果写入到trace文件目录
使用Oracle提供的tkprof来格式化打开追踪文件,进行分析,如下:
tkprof ora_2229_10046.trc 888.trc
vim 888.trc
---开启会话跟踪:alter system set events ‘10046 trace name context forever, level 12’;
---关闭会话跟踪:alter system set events ‘10046 trace name context off’;
---收集特定session的10046
SPID 是操作系统的进程标识符(os pid)
PID 是Oracle的进程标识符(ora pid)
假设需要被跟踪的OSPID是9834,以sysdba的身份登录到SQL*Plus并执行下面的命令:
oradebug setospid 9834
oradebug unlimit
oradebug event 10046 trace name context forever,level 12

注:也可以通过oradebug使用 'setorapid'命令连接到一个session。
下面的例中, 使用PID(Oracle进程标识符)(而不是SPID), oradebug命令将被改为:

connect as sysdba
oradebug setorapid 9834
oradebug unlimit
oradebug event 10046 trace name context forever,level 12
跟踪过程完成以后,关闭oradebug跟踪:
oradebug event 10046 trace name context off

1、产生原因
该等待事件通常发生在数据库多块读时,表示发生了与全表扫描和快速索引扫描相关的等待。通常意味着全表扫描过多,或者I/O 能力不足,或者I/O 竞争。
2、确定产生问题对象方法
a)查找全表扫描的SQL 语句可以使用以下语句:
select sql_text
from v$sqltext t, v$sql_plan p
where t.hash_value = p.hash_value
and p.operation = 'TABLE ACCESS'
and p.options = 'FULL'
order by p.hash_value, t.piece;

b)查找Fast Full Index 扫描的SQL 语句可以使用以下语句:
select sql_text
from v$sqltext t, v$sql_plan p
where t.hash_value = p.hash_value
and p.operation = 'INDEX'
and p.options = 'FULL SCAN'
order by p.hash_value, t.piece;

3、解决办法
(1)在合适的字段上建立索引把表的访问方式从全表扫描变为索引扫描可以有效地降低物理IO。
(2)对于大表,在合适的字段,比如年月、地区编码上建立分区把全表扫描变成分区扫描以减少物理IO。
(3)把需要经常扫描的数据库表放在KEEP 池同样会有效地降低物理IO。
(4)调整db_file_multiblock_read_count值,以达到每次读取更多数据块的目的。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论