read by other session等待事件概述
?
當(dāng)從數(shù)據(jù)庫請(qǐng)求信息時(shí),Oracle將首先將數(shù)據(jù)從磁盤讀入數(shù)據(jù)庫緩沖區(qū)緩存。如果兩個(gè)或多個(gè)會(huì)話請(qǐng)求相同的信息時(shí),則第一個(gè)會(huì)話將數(shù)據(jù)讀入buffer cache的過程中,而其他會(huì)話出現(xiàn)等待。在之前的數(shù)據(jù)庫版本中,此等待事件被歸類為“buffer busy waits”等待事件。 但是,在Oracle 10.1及更高版本中,此等待時(shí)間現(xiàn)在劃分為“read by other session”等待事件,是oracle 10g 從oracle 9i的buffer busy waits中分離出來的,也是一種熱塊現(xiàn)象。
該等待事件的大量等待通常是由于一些進(jìn)程重復(fù)讀取相同的數(shù)據(jù)塊,例如, 許多會(huì)話掃描同一索引或在同一個(gè)表上執(zhí)行全表掃描。 調(diào)優(yōu)此問題是找到并消除這種競(jìng)爭(zhēng)。read by other session等待的出現(xiàn)也說明數(shù)據(jù)庫存在讀的競(jìng)爭(zhēng),等待事件read by other session 通常與等待事件db file scattered read 和db file sequential read同時(shí)出現(xiàn)。有時(shí)候甚至與等待事件enq: TX - row lock contention同時(shí)出現(xiàn)(特殊情況,一個(gè)特殊案例中遇到的,等待read by other session的會(huì)話阻塞其它會(huì)話)。db file scattered read通常顯示與全表掃描相關(guān)的等待。當(dāng)數(shù)據(jù)庫進(jìn)行全表掃時(shí),基于性能的考慮,數(shù)據(jù)會(huì)分散(scattered)讀入Buffer Cache。如果這個(gè)等待事件比較顯著,可能說明對(duì)于某些全表掃描的表,沒有創(chuàng)建索引或者沒有創(chuàng)建合適的索引。db file sequential read通常顯示與單個(gè)數(shù)據(jù)塊相關(guān)的讀取操作(如索引讀取)。如果這個(gè)等待事件比較顯著,可能表示在多表連接中,表的連接順序存在問題,可能沒有正確的使用驅(qū)動(dòng)表;或者可能說明不加選擇地進(jìn)行索引。
當(dāng)出現(xiàn)該問題如何解決?
一般出現(xiàn)該問題是由于sql導(dǎo)致的,或者是由于磁盤設(shè)備可能導(dǎo)致。
當(dāng)出現(xiàn)該問題的時(shí)候,首先需要定位sql。
方法一:通過ash獲得細(xì)粒度的報(bào)告,查看top sql statement 獲得sql。
方法二:通過sql語句直接獲得:
1、當(dāng)前正在發(fā)生的問題:
select sql_fulltext from v$sql a,v$session b where a.sql_id=b.sql_id and b.event='read by other session';
2、歷史曾經(jīng)發(fā)生的
select a.sql_id,sql_fulltext from v$sql a,dba_hist_active_sess_history b where a.sql_id=b.sql_id and b.event='read by other session';
另外可以查看涉及對(duì)象信息,此處就是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';
根據(jù)FILE#,BLOCK#查詢熱塊對(duì)象
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME
FROM DBA_EXTENTS A
WHERE FILE_ID = &FILE_ID
AND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS – 1;
另外,直接查找熱點(diǎn)塊對(duì)象語句
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
直接查找熱點(diǎn)塊操作語句
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;
找到sql之后需要做的就是查看執(zhí)行計(jì)劃,判斷問題所在,并進(jìn)行優(yōu)化。
