正常情况下,db file sequential read是由于索引扫描引起,在TOP 5中排在第四或第五位是正常的,无须过多关注,
但是今天它跑到了第一位,并且伴随着read by other session那就说明问题了,
首先我们知道read by other session等待的原理是多个会话并发将同一数据块从磁盘读入SGA,但ORACLE同一时间只允许一个会话从磁盘将同一数据块读入SGA,在并发情况下其它session必须等待,因此就有了read by othersession等待事件,结合两个等待事件原理,我们基本上可以断定,系统发生了高并发查询,并且从log file sync等待事件来看,系统发生了频率的提交操作,导致数据库日志频率同步,实际情况是不是这样呢?这一点我们可以从Load Profile和TOP SQL部分可以得到验证,
当从数据库请求信息时,Oracle将首先将数据从磁盘读入数据库缓冲区缓存。如果两个或多个会话请求相同的信息时,则第一个会话将数据读入buffer cache的过程中,而其他会话出现等待。在之前的数据库版本中,此等待事件被归类为“buffer busy waits”等待事件。 但是,在Oracle 10.1及更高版本中,此等待时间现在划分为“read by other session”等待事件。 该等待事件的大量等待通常是由于一些进程重复读取相同的数据块,例如, 许多会话扫描同一索引或在同一个表上执行全表扫描。 调优此问题是找到并消除这种竞争。
需要访问的数据块不在内存里,因此不得不把数据块从磁盘LOAD到内存的过程中,另一个/些(假设进程B、C)也要读取这个数据块,这个时候进程A发生的等待可能是 /db file db file sequential readparallel read/db file scattered read 中的某一个或某几个,而进程 B、C 发生的等待就是我们今天要介绍的 Read By Other Session,Oracle 不会让多个进程去同时物理读取一个数据块 LOAD 入共享内存,只会让第一个进程去DISK读取,然后放入共享内存,这么做也是为了保护共享内存。
read by other session的介绍
This event occurs when a session requests a buffer that is currently being read into the buffer cache by another session. Prior to release 10.1, waits for this event were grouped with the other reasons for waiting for buffers under the 'buffer busy waits' event
Wait Time: Time waited for the buffer to be read by the other session (in microseconds)
read by other session的分析
read by other session等待的出现也说明数据库存在读的竞争,等待事件read by other session 通常与等待事件db file scattered read 和db file sequential read同时出现。有时候甚至与等待事件enq: TX - row lock contention同时出现(特殊情况,一个特殊案例中遇到的,等待read by other session的会话阻塞其它会话),如下截图所示。
db file scattered read通常显示与全表扫描相关的等待。当数据库进行全表扫时,基于性能的考虑,数据会分散(scattered)读入Buffer Cache。如果这个等待事件比较显著,可能说明对于某些全表扫描的表,没有创建索引或者没有创建合适的索引。
db file sequential read通常显示与单个数据块相关的读取操作(如索引读取)。如果这个等待事件比较显著,可能表示在多表连接中,表的连接顺序存在问题,可能没有正确的使用驱动表;或者可能说明不加选择地进行索引。
read by other session解决
1.数据库等待event占比最高是read by other session ,这个意思是一个会话a执行查询blocks,正在被另一个会话从磁盘读取到内存中,我的会话a只需要等待即可,到时候从内存中获取记录;
2.观察top sql SQL ordered by Reads
Captured SQL account for 100.2% of Total
基本上物理读都包含在top sql中,top sql占比最高的两条sql 6suqju7ut3vub,dbfmq27nhyn29 均为动态采样的SQL对象为"ASSP2".“ASSP_CLOB_VOUCHER_STAMP_2020”
主要查看等待事件及Segment by Physical Read Requests 列表
这个对象检索可以发现有sql 执行这个对象相关的sql;
3.建议
3.1先确认这个表有没有合适的统计信息,是否是简单的由于表没有统计信息造成执行sql需要执行动态采样,手工收集下表的统计信息
3.2 采用之前同事的方法,检查参数是否修改optimizer_dynamic_sampling
3.3 采用之前同事的方法,禁用动态采样
如何查看当前会话处于等待read by other session:
使用下面SQL找到当前处于read by other session等待的SQL语句,然后分析SQL,优化SQLSELECT s.username, s.sid, s.serial#, s.osuser, s.machine, s.terminal, s.program, s.last_call_et, s.event, s.seconds_in_wait, s.blocking_session, t.sql_text --,t.SQL_FULLTEXT FROM v$session s, v$sqlarea t WHERE s.sql_address = t.address AND S.sid IN (SELECT sid FROM v$session_wait WHERE event IN ( 'read by other session' ));
或
select sql_fulltext from v$sql a,v$session b where a.sql_id=b.sql_id and b.event='read by other session';
也可以通过下面SQL,获取产生read by other session等待事件的SQL的实际执行计划,研究执行计划后,对相关SQL进行调优,例如,对于全表扫描的添加合适索引。SELECT DISTINCT SQL_IDFROM V$SESSIONWHERE EVENT IN('read by other session', 'db file sequential read'); SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('xxxxx'));
对于非当前会话的read by other session等待事件,我们可以通过AWR报告和ASH结合,找到发生read by other session等待的SQL语句。
1:首先分析Top 5 Timed Events,分析read by other session、db file scattered read、db file sequential read等待事件
2:AWR报告中分析Segments by Buffer Busy Waits部分内容
如下截图所示,基本上可以判断第一个表xxx就是出现
3:首先使用下面脚本找到产生了'read by other session'等待事件的SQL,然后生成指定SQL语句的统计报表(awrsqrpt.sql)以及接近采样点附近的ASH报告SELECT a.sql_id, sql_fulltextFROM v$sql a, dba_hist_active_sess_history bWHERE a.sql_id = b.sql_id AND b.event = 'read by other session';
AWR报告里面的SQL ordered by Reads 或SQL ordered by Gets中的TOP SQL找到涉及Segments by Buffer Busy Waits中对象的SQL ,然后结合ASH(细粒度的报告)来判断、分析!。
另外,如果需要查看涉及对象信息,可以通过等待事件的字段p1,p2,p3来获取
SELECT p1 "file#" , p2 "block#" , p3 "class#" FROM v$session_wait WHERE event = 'read by other session';
或
SELECT p1 "file#" ,p2 "block#" ,p3 "class#"FROM dba_hist_active_sess_history WHERE event = 'read by other session';
官方文档描述如下:
· P1 = file# Absolute File# (AFN)
· P2 = block#
· P3 = class# Block class
· file# Absolute File Number (AFN)
This is the file number of the data file that contains the block that the waiting session wants.
· block#
This is the block number in the above file# that the waiting session wants access to. See Note:181306.1 to determine the tablespace, filename and object for this file#,block# pair.
· class# Block class#
This is the class of block being waited on. In particular:
class 1 indicates a "data block", which could be table or index
class 4 indicates a "segment header"
class >=15 indicate undo blocks
另外,下面一些SQL“Read by other session等待事件”,非常有用。
根据FILE#,BLOCK#查询热块对象SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAMEFROM DBA_EXTENTS AWHERE FILE_ID = &FILE_IDAND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS – 1;
直接查找热点块对象语句SELECT * FROM (SELECT O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE, SUM(TCH) TOUCHTIME FROM X$BH B, DBA_OBJECTS O WHERE B.OBJ = O.DATA_OBJECT_ID AND B.TS# > 0 GROUP BY O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE ORDER BY SUM(TCH) DESC) WHERE ROWNUM <= 10
--或者SELECT E.OWNER, E.SEGMENT_NAME, E.SEGMENT_TYPE FROM DBA_EXTENTS E, (SELECT * FROM (SELECT ADDR, TS#, FILE#, DBARFIL, DBABLK, TCH FROM X$BH ORDER BY TCH DESC) WHERE ROWNUM < 11) B WHERE E.RELATIVE_FNO = B.DBARFIL AND E.BLOCK_ID <= B.DBABLK AND E.BLOCK_ID + E.BLOCKS > B.DBABLK
直接查找热点块操作语句SELECT /*+rule*/ HASH_VALUE, SQL_TEXT FROM V$SQLTEXT WHERE (HASH_VALUE, ADDRESS) IN (SELECT A.HASH_VALUE, A.ADDRESS FROM V$SQLTEXT A, (SELECT DISTINCT A.OWNER, A.SEGMENT_NAME, A.SEGMENT_TYPE FROM DBA_EXTENTS A, (SELECT DBARFIL, DBABLK FROM (SELECT DBARFIL, DBABLK FROM X$BH ORDER BY TCH DESC) WHERE ROWNUM < 11) B WHERE A.RELATIVE_FNO = B.DBARFIL AND A.BLOCK_ID <= B.DBABLK AND A.BLOCK_ID + A.BLOCKS > B.DBABLK) B WHERE A.SQL_TEXT LIKE '%' || B.SEGMENT_NAME || '%' AND B.SEGMENT_TYPE = 'TABLE') ORDER BY HASH_VALUE, ADDRESS, PIECE;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




