背景
在很多情況下,當資料庫發生效能問題的時候,我們並沒有機會來收集足夠的診斷資訊,比如system state dump或者hang analyze,甚至問題發生的時候dba根本不在場。這給我們診斷問題帶來很大的困難。那麼在這種情況下,我們是否能在事後收集一些資訊來分析問題的原因呢?在oracle 10g或者更高版本上,答案是肯定的。本文我們將介紹一種通過dba_hist_active_sess_history的資料來分析問題的一種方法。
適用於
oracle 10g或更高版本,本文適用於任何平台。
詳情
在oracle 10g中,我們引入了awr和ash取樣機制,有乙個檢視gv$active_session_history會每秒鐘將資料庫所有節點的active session取樣一次,而dba_hist_active_sess_history則會將gv$active_session_history裡的資料每10秒取樣一次並持久化儲存。基於這個特徵,我們可以通過分析dba_hist_active_sess_history的session取樣情況,來定位問題發生的準確時間範圍,並且可以觀察每個取樣點的top event和top holder。下面通過乙個例子來詳細說明。
1. dump出問題期間的ash資料:
為了不影響生產系統,我們可以將問題大概期間的ash資料export出來在測試機上分析。
基於dba_hist_active_sess_history建立乙個新錶m_ash,然後將其通過exp/imp匯入到測試機。在發生問題的資料庫上執行exp:
sql> conn user/passwd
sql> create table m_ash as select * from dba_hist_active_sess_history where sample_time between to_timestamp ('', 'yyyy-mm-dd hh24:mi:ss') and to_timestamp ('', 'yyyy-mm-dd hh24:mi:ss');
$ exp user/passwd file=m_ash.dmp tables=(m_ash) log=m_ash.exp.log
然後匯入到測試機:
$ imp user/passwd file=m_ash.dmp log=m_ash.imp.log
2. 驗證匯出的ash時間範圍:
為了加快速度,我們採用了並行查詢。另外建議採用oracle sql developer來查詢以防止輸出結果折行不便於觀察。
set line 200 pages 1000
col sample_time for a25
col event for a40
alter session set nls_timestamp_format='yyyy-mm-dd hh24:mi:ss.ff';
select /*+ parallel 8 */
t.dbid, t.instance_number, min(sample_time), max(sample_time), count(*) session_count
from m_ash t
group by t.dbid, t.instance_number
order by dbid, instance_number;
instance_number min(sample_time) max(sample_time) session_count
1 2015-03-26 21:00:04.278 2015-03-26 22:59:48.387 2171
2 2015-03-26 21:02:12.047 2015-03-26 22:59:42.584 36
從以上輸出可知該資料庫共2個節點,取樣時間共2小時,節點1的取樣比節點2要多很多,問題可能發生在節點1上。
3. 確認問題發生的精確時間範圍:
參考如下指令碼:
select /*+ parallel 8 */
dbid, instance_number, sample_id, sample_time, count(*) session_count
from m_ash t
group by dbid, instance_number, sample_id, sample_time
order by dbid, instance_number, sample_time;
instance_number sample_id sample_time session_count
1 36402900 2015-03-26 22:02:50.985 4
1 36402910 2015-03-26 22:03:01.095 1
1 36402920 2015-03-26 22:03:11.195 1
1 36402930 2015-03-26 22:03:21.966 21
1 36402940 2015-03-26 22:03:32.116 102
1 36402950 2015-03-26 22:03:42.226 181
1 36402960 2015-03-26 22:03:52.326 200
1 36402970 2015-03-26 22:04:02.446 227
1 36402980 2015-03-26 22:04:12.566 242
1 36402990 2015-03-26 22:04:22.666 259
1 36403000 2015-03-26 22:04:32.846 289
1 36403010 2015-03-26 22:04:42.966 147
1 36403020 2015-03-26 22:04:53.076 2
1 36403030 2015-03-26 22:05:03.186 4
1 36403040 2015-03-26 22:05:13.296 1
1 36403050 2015-03-26 22:05:23.398 1
注意觀察以上輸出的每個取樣點的active session的數量,數量突然變多往往意味著問題發生了。從以上輸出可以確定問題發生的精確時間在2015-03-26 22:03:21 ~ 22:04:42,問題持續了大約1.5分鐘。
注意: 觀察以上的輸出有無斷檔,比如某些時間沒有取樣。
4. 確定每個取樣點的top n event:
在這裡我們指定的是top 2 event��並且注掉了取樣時間以觀察所有取樣點的情況。如果資料量較多,您也可以通過開啟sample_time的注釋來觀察某個時間段的情況。注意最後一列session_count指的是該取樣點上的等待該event的session數量。
select t.dbid,
t.sample_id,
t.sample_time,
t.instance_number,
t.event,
t.session_state,
t.c session_count
from (select t.*,
rank() over(partition by dbid, instance_number, sample_time order by c desc) r
from (select /*+ parallel 8 */
t.*,
count(*) over(partition by dbid, instance_number, sample_time, event) c,
row_number() over(partition by dbid, instance_number, sample_time, event order by 1) r1
from m_ash t
/*where sample_time >
to_timestamp('2013-11-17 13:59:00',
'yyyy-mm-dd hh24:mi:ss')
and sample_time <
to_timestamp('2013-11-17 14:10:00',
'yyyy-mm-dd hh24:mi:ss')*/
) twhere r1 = 1) t
where r < 3
order by dbid, instance_number, sample_time, r;
如何通過Matplotlib畫圓
前兩天因為需要,嘗試著用matplotlib 中的pyplot畫圓我畫圓的方法是通過圓的方程來畫的,另外在圖中做了必要的說明。半徑為1,圓心為 2,2 方程分為兩個,話不多說,直接看 import numpy as np import matplotlib.pyplot as plt x 1,1.5...
如何配置ArcGIS DeskTop通過防火牆
現在許多網路使用者使用防火牆來抵禦外界威脅。因為arcgis license manager使用tcp ip協議,使用這些防火牆會帶來一些licence manager和客戶端連線的一些問題。造成這個問題的原因是防火牆通常把licence manager用於通訊的埠關閉或者阻止引起的。預設情況下,如...
如何通過模板限制型別
模板的作用是把一組不相關的資料型別作為通用型進行抽象,這樣實現泛型。但反過來看如何限制型別呢比如我要限制char型別的生成。這個問題其實可以用模板特化實現。includeusing namespace std templateclass contan template class contan te...