一、表空間信息查詢慢
前幾天跟銷售拜訪潛在客戶時(shí),客戶提到他們近期很頭疼的問題:他們自己寫的一個(gè)查詢表空間的語句從上周開始跑不出來了,做了很多嘗試未果,比較苦惱,畢竟作為DBA不知道庫的空間使用情況,客戶心里是有點(diǎn)發(fā)毛的。
聽完客戶描述,我也馬上回復(fù)說這個(gè)問題很常見,都在我們?nèi)粘Q矙z的范圍內(nèi),解決起來很簡(jiǎn)單。一般查詢表空間的語句都是用到了DBA_FREE_SPACE這張視圖,查詢起來慢,常見原因一般如下:
數(shù)據(jù)字典信息/固化視圖統(tǒng)計(jì)信息過舊;
回收棧內(nèi)對(duì)象過多。
處理方式:
exec dmbs_stats.gather_fixed_objects_stats;
exec dbms_stats.gather_dictionary_stats(degree =>8,cascade =>true);
purge recyclebin;
客戶聽完介紹的解決方案,表示認(rèn)同并希望現(xiàn)場(chǎng)幫他們處理好問題,熱情地帶我去他的工位。雖然庫并非生產(chǎn)數(shù)據(jù)庫,但訪問這個(gè)庫依然需要通過堡壘機(jī),而且命令需要手敲。
客戶的演示
客戶通過shell腳本SQLplus進(jìn)入數(shù)據(jù)庫后運(yùn)行語句類似以下SQL:
SELECT UPPER(F.TABLESPACE_NAME) AS "表空間名稱",
ROUND(D.AVAILB_BYTES ,2) AS "表空間大小(G)",
ROUND(D.MAX_BYTES,2) AS "最終表空間大小(G)",
ROUND((D.AVAILB_BYTES - F.USED_BYTES),2) AS "已使用空間(G)",
TO_CHAR(ROUND((D.AVAILB_BYTES - F.USED_BYTES) / D.AVAILB_BYTES * 100,
2), '999.99') AS "使用比",
ROUND(F.USED_BYTES, 6) AS "空閑空間(G)",
F.MAX_BYTES AS "最大塊(M)"
FROM (
SELECT TABLESPACE_NAME,
ROUND(SUM(BYTES) / (1024 * 1024 * 1024), 6) USED_BYTES,
ROUND(MAX(BYTES) / (1024 * 1024 * 1024), 6) MAX_BYTES
FROM SYS.DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F,
(SELECT DD.TABLESPACE_NAME,
ROUND(SUM(DD.BYTES) / (1024 * 1024 * 1024), 6) AVAILB_BYTES,
ROUND(SUM(DECODE(DD.MAXBYTES, 0, DD.BYTES, DD.MAXBYTES))/(1024*1024*1024),6) MAX_BYTES
FROM SYS.DBA_DATA_FILES DD
GROUP BY DD.TABLESPACE_NAME) D
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME
ORDER BY 4 DESC
客戶運(yùn)行了腳本,果然卡住了一樣,無返回結(jié)果。演示完,客戶讓出了座位,示意我可以上機(jī)操作了。因?yàn)椴皇巧a(chǎn)庫,客戶也表示可以隨意操作,于是沒有去進(jìn)一步確認(rèn)信息,順利完成了上面列的操作。
有趣的地方來了
客戶開始驗(yàn)證效果的時(shí)候,比較尷尬,依然卡在那兒。客戶地方?jīng)]有監(jiān)控,也沒有我習(xí)慣的腳本,客戶打開plSQLdeveloper后,我看了一下在運(yùn)行的SQL等待事件是單塊兒讀,我有點(diǎn)猶豫要不要手敲那些工具SQL的時(shí)候,有趣的地方也來了~ 客戶的DBA開始討論起了原因:
一個(gè)客戶DBA說,他覺得是IO太慢,因?yàn)閹觳皇欠旁诖鎯?chǔ)上的,而且raid可能用的是raid 5之類。
另一個(gè)客戶DBA說,可能是數(shù)據(jù)庫太大了,性能有影響。
為了避免問題走偏,我快速打了個(gè)快照,做了awr報(bào)告,確認(rèn)了一下單塊讀約3ms,數(shù)據(jù)文件個(gè)數(shù)約800個(gè)。證偽了以上假設(shè)。
那到底為什么SQL查詢還是不快呢?我有點(diǎn)猶豫,畢竟堡壘機(jī)命令都手敲不能直接跑自己的腳本包。客戶主要負(fù)責(zé)的DBA此時(shí)主動(dòng)給臺(tái)階讓我下,讓我找時(shí)間再看看,回去了再研究,畢竟他們也快下班了。
意外的效果
這個(gè)臺(tái)階當(dāng)然不能下…… 在10046跟moitor報(bào)告中,個(gè)人還是更傾向monitor報(bào)告,于是腳本加了monitor的hint,打算再跑一次。另外一個(gè)會(huì)話準(zhǔn)備編寫腳本的時(shí)候,SQL瞬間出了結(jié)果。常用腳本這里也貼一下:
set pagesize 0 echo off timing off linesize 1000 trimspool on trim on long 2000000 longchunksize 2000000 feeDBAck off
spool &1..&2
--active/html/EM
select dbms_SQLtune.report_SQL_monitor(type=>'&2', SQL_id=>'&1', SQL_exec_id=>null, report_level=>'ALL') monitor_report from dual;
spool off
客戶DBA說這個(gè)hint有效果,但是我也不打算糊弄客戶,跟客戶解釋了這個(gè)hint跟跑起來快了沒什么關(guān)系,并用 /*+ xxx */這個(gè)改動(dòng),再次運(yùn)行,果然也很快??蛻暨\(yùn)行原來的語句,依然跑不出來。這時(shí)候,基本已經(jīng)知道原因了。
雖然講道理,收集了統(tǒng)計(jì),SQL的執(zhí)行計(jì)劃應(yīng)該是會(huì)失效,并重新解析的,這里顯然那個(gè)SQL的執(zhí)行計(jì)劃應(yīng)該還是原來的,沒有變動(dòng)。考慮到不是生產(chǎn)庫,就直接flush了shared pool。再次運(yùn)行那個(gè)問題SQL,順利秒出結(jié)果。
二、ASH信息采集慢
某客戶反饋監(jiān)控上線后,在監(jiān)控的數(shù)十套數(shù)據(jù)庫中有一套庫監(jiān)控SQL的數(shù)據(jù)庫時(shí)間占比較高,監(jiān)控自身顯示是一條采集ASH數(shù)據(jù)的語句。經(jīng)過了解,其他庫該語句執(zhí)行均在1s以內(nèi),在其中一個(gè)數(shù)據(jù)庫上運(yùn)行時(shí)間可達(dá)4分鐘,監(jiān)控中我們馬上發(fā)現(xiàn)了該SQL的監(jiān)視報(bào)告。
監(jiān)視報(bào)告快速定位
打開報(bào)告,通過Wait Activity中可發(fā)現(xiàn)55%時(shí)間是read by other session等待事件,還有36%為gc相關(guān)等待事件,結(jié)合2GB的IO,可以基本可知問題原因?yàn)镾QL讀取IO量過多,在RAC高并發(fā)環(huán)境下,性能問題被放大
閱讀全文請(qǐng)點(diǎn)擊http://click.aliyun.com/m/1000003871/