1. 程式人生 > >等待事件 db file scattered read

等待事件 db file scattered read

 db file scattered read 等待事件,在生產環境之中,這個等待事件可能更為常見。 這個事件表明使用者程序正在讀資料到 Buffer Cache 中,等待直到物理 I/O呼叫返回。 DB File Scattered Read 發出離散讀,將儲存上連續的資料塊離散的讀入到多個不連續的記憶體位置。 Scattered Read 通常是多塊讀,在 Full Table Scan 或 Fast Full Scan 等訪問方式下使用。

Scattered Read 代表 Full Scan,當執行 Full Scan 讀取資料到 Buffer Cache 時,通常連續的資料在記憶體中的儲存位置並不連續,所以這個等待被命名為 Scattered Read( 離散讀)。每次多

塊讀讀取的資料塊數量受初始化引數            DB_FILE_MULTIBLOCK_READ_COUNT 限制。 圖簡要說明了 Scattered Read 的資料讀取方式

從 V$EVENT_NAME 檢視可以看到,該等待有 3 個引數,分別代表檔案號、 起始資料塊號、 資料塊的數量:

 

SQL> select * from v$event_name where name='db file scattered read';

EVENT# NAME PARAMETER1 PARAMETER2 PARAMETER3

---------- ---------------------- ---------------------- ------------- ----

206 db file scattered read file# block# blocks

資料檔案號、起始資料塊號加上資料塊的數量, 通過這些資訊可以知道 Oracle Session 正在等待的物件檔案等資訊。 該等待可能和全表掃描( Full Table Scan)或者快速全索引掃描( Index Fast Full Scan) 的連續讀取相關, 根據經驗, 通常大量的 db file scattered read 等待可能意味著應用問題或者索引缺失。

在實際環境的診斷過程中, 可以通過 v$session_wait 檢視發現 Session 的等待,再結合其他檢視找到存在問題的 SQL 等根本原因,從而從根本上解決問題。

當這個等待事件比較顯著時, 使用者也可以結合 v$session_longops 動態效能檢視來進行診斷,該檢視中記錄了長時間(執行時間超過 6 秒的)執行的事務,可能很多是全表掃描操作(不管怎樣,這部分資訊都是值得我們注意的),上一個案例就是通過 v$session_longops 快速發現了問題所在。

從 Oracle 9i 開始, Oracle 新增加了一個檢視 V$SQL_PLAN 用於記錄當前系統 Library Cache 中 SQL 語句的執行計劃, 可以通過這個檢視找到存在問題的 SQL 語句, 以下是在一個

生產系統中查詢得到的結果:

SQL> @getplan

Enter value for waitevent: free buffer waits

old 15: AND b.event = '&waitevent')

new 15: AND b.event = 'free buffer waits')

HASH_VALUE CHILD_NUMBER OPERATION OBJECT COST KBYTES

---------- ------------ ---------------------------------------- -------------------

2838180055 0 INSERT STATEMENT CHOOSE Cost=41733 41733

2838180055 0 TABLE ACCESS FULL I_CM_POWER_TEMP 41733 1356468

進而可以通過 v$sql_text 檢視獲得這個問題 Session 正在執行的 SQL 語句:

SQL> select sid,event from v$session_wait;

SID EVENT

---------- ----------------------------------------------------------------

1 pmon timer

4 rdbms ipc message

7 rdbms ipc message

5 rdbms ipc message

8 rdbms ipc message

21 free buffer waits

49 free buffer waits

2 db file parallel write

 

3 db file parallel write

6 smon timer

……

16 rows selected.

 

SQL>@ GetSqlBySid

Enter value for sid: 49

old 5: where b.sid='&sid'

new 5: where b.sid='49'

SQL_TEXT

-----------------------------------------------------------------------

insert into i_cm_power_new(PNAME,YYS,SPHM,SJH,SENTTIME,NOTES,PLACE,RMK)

select PNAME,YYS,SPHM,SJH,SENTTIME,NOTES,PLACE,RMK FROM i_cm_power_temp

通過 V$SQL_PLAN 檢視, 可以獲得大量有用的資訊,比如獲得全表掃描的物件:

SQL> select distinct object_name,object_owner from v$sql_plan p

2 where p.operation='TABLE ACCESS' and p.options='FULL'

3 and object_owner = 'MKT';

OBJECT_NAME OBJECT_OWNER

--------------------------------------------------- -----------------

HD_TEMP MKT

I_CM_BILL MKT

I_CM_IVR_BUTTON MKT

……

TOOLS_HD MKT

TOOLS_HD_NEW MKT

TOOLS_HD_NEW_BAK MKT

TOOLS_IVRBLIST MKT

TOOLS_USER_CANCEL MKT

29 rows selected

或者獲得全索引掃描物件:

SQL> select distinct object_name,object_owner from v$sql_plan p

2 where p.operation='INDEX' and p.options='FULL SCAN' ;

OBJECT_NAME OBJECT_OWNER

------------------------------ -----------------------------------

FK_ITEM_LEVEL_CODE AVATAR

FK_ITEM_SELLCNT_CODE AVATAR

FK_MYZZIM_CRTDATE AVATAR

I_SYSAUTH1 SYS

SYS_C008211 WLLM

進而可以通過 V$SQL_PLAN 和 V$SQLTEXT 聯合,獲得這些查詢的 SQL 語句, 查詢全

 

表掃描的 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;

查詢 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;

這些資訊對於發現數據庫問題,優化資料庫效能具有極強的指導意義。 本例中用到的 SQL

程式碼 getplan.sql 內容如下: :

SET linesize 120

COL operation format a55

COL cost format 99999

COL kbytes format 999999

COL object format a25

SELECT hash_value, child_number, LPAD (' ', 2 * DEPTH) || operation || ' ' || options

|| DECODE (ID, 0, SUBSTR (optimizer, 1, 6) || ' Cost=' || TO_CHAR (COST) ) operation,

object_name OBJECT, COST, ROUND (BYTES / 1024) kbytes

FROM v$sql_plan WHERE hash_value IN (

SELECT a.sql_hash_value FROM v$session a, v$session_wait b

WHERE a.SID = b.SID AND b.event = '&waitevent')

ORDER BY hash_value, child_number, ID;

在 Oracle 10g 中, Oracle 對等待事件進行了分類, db file scattered read 事件被歸入 User I/O

一類:

SQL> select name,PARAMETER1 p1,PARAMETER2 p2,PARAMETER3 p3,

2 WAIT_CLASS_ID,WAIT_CLASS#,WAIT_CLASS

3 from v$event_name where name='db file scattered read';

NAME P1 P2 P3 WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS

------------------------- -------- -------- -------- ------------- ----------- ----------

db file scattered read file# block# blocks 1740759767 8 User I/O

 

 

下面是一條有用的SQL語句,在資料庫層面檢視db file等待事件的I/O是否有問題。

############################  IO 響應時間     ############################  

select to_char(b.begin_interval_time,'yyyy-mm-dd:hh24'),a.event_name,a.avg_time

from (

select event_name,snap_id,round(lag_time/lag_count/1000,2) avg_time from (

select event_name,snap_id,total_waits-lag(total_waits,1,total_waits) over(partition by event_name,instance_number order by snap_id) lag_count,

time_waited_micro-lag(time_waited_micro,1,time_waited_micro) over(partition by event_name,instance_number order by snap_id) lag_time

 from dba_hist_system_event where event_name in ('db file scattered read') <==========這個地方要檢查db file sequential read 和 db file scattered read

and instance_number=1) where lag_count>0) a,dba_hist_snapshot b

where b.instance_number=1 <=============這個地方要檢查例項1和例項2

and a.snap_id=b.snap_id

order by 2,1;