數據庫慢一般有三種情況
逐漸變慢
突然變慢
不定時變慢
第一種情況 逐漸變慢要建立一個長期的監控機制比如寫個shell腳本每天的忙時(通常~ etc)定時收集osnetworkdb的信息 每個星期出report對收集到的信息進行分析這些數據的積累可以決定後期的優化決策並且可以是DBA說服manager采用自己決策的重要數據DBA的價值就在每個星期的report中體現
第二種情況 突然變慢也是最容易解決的先從業務的角度看是DB的使用跟以前有何不同然後做進一步判斷硬件/網絡故障通常也會引起DB性能的突然下降
第一步: 察看DB/OS/NETWORK的系統log 排除硬件/網絡問題
第二步察看數據庫的等待事件根據等待事件來判斷可能出問題的環節如果 沒有等待事件 可以排除數據庫的問題 如果有等待時間 根據不同的等待事件 來找引起這些事件的根源
比如latch free等跟SQL parse有關系的等待事件OS的表現是CPU 的占用率高
db file scattered read等跟SQL disk read有關系的等待時間 OS的表現是iostat可以看到磁盤讀寫量增加
第三步: 察看os的信息 CPU/IO/MEMORY等
a Cpu 的占用率
CPU占用率與數據庫性能不成反比 CPU占用率高 不能說明數據庫性能慢 通常情況 一個優化很好 而且業務量確實很大的數據庫 CPU的占用率都會高 而且會平均分布在每個進程上 反過來 CPU的占用率都會高也不代表數據庫性能就好 要結合數據庫的等待事件來判斷CPU占用率高是否合理
如果某個進程的cpu占用高 肯定是這個進程有問題 如果不是oracle的進程 可以讓application察看是否程序有死循環等漏洞 如果是oracle的進程 可以根據pid查找oracle數據字典看看這個進程的發起程序 正在執行的sql語句 以及等待事件 然後 不同情況使用不同的方法來解決
b IO
排除硬件的IO問題 數據庫突然變慢 一般來說 都是一個或幾個SQL語句引起的
如果IO很頻繁 可以通過優化disk reads高的TOP SQL來解決 當然這也是解決IO問題的最笨也是最有效的辦法
OS以及存儲的配置也是影響IO的一個重要的原因
比如 最常見的HPunix下異步IO的問題 如果DBA GROUP沒有MLOCK的權限 ORACLE是不使用AIO的 偏偏OS與DB的兩方的admin如果配合不夠好地話 這個配置就很容易給漏掉了
c Memory
第二種情況與memory的關系比較小 只要SGA區配置合理沒有變化 一般來說 只要不是Application Memory leak 不會引起突然變慢的現象
第三種情況 不定時變慢 是最難解決的 現場出現的問題原因也是五花八門千奇百怪 最重要的是 出現慢的現象時 以最快的速度抓取到最多的信息以供分析 先寫好抓取數據的shell 腳本 並在現象發生時及時按下回車鍵
一個例子
數據庫突然變慢
背景: 一個新應用上線後 數據庫突然變慢
第一步 調查新應用
據開發人員講新應用訪問的都是新建立的表 表的數據量很小 沒有復雜的SQL查詢
查詢 v$sqlarea 分別按照disk_reads / buffer_gets / executions 排序 TOP SQL 中沒有新應用的SQL 排除新應用數據庫訪問照成的性能問題
第二步 察看數據庫log/ OS log
數據庫log中可以看到大量的ORA錯誤 以及大量的dump文件 分析dump文件(時間久了沒有dump文件可參考 具體細節沒法描述下來 ) 發現是新應用通過dblink訪問remote DB時生成的dump文件 應用開發人說沒法修改 Oracle也沒有相應的patch解決
OS log中沒有錯誤信息
第三步 察看statspack report
從wait events中看到Top event是buffer busy waits db file parallel write 等於IO相關的等待事件
從buffer busy waits 的統計信息來看 是等待data block
還有些physical reads等信息與從前比沒有太多的異常
Tablespace 的IO reads/writes也沒有異常 但是wait明顯增加
初步確定是IO問題
第四步 察看OS的信息
top 命令(輸出為實驗室數據僅作格式參考)
load averages: ::
processes: sleeping zombie stopped on cpu
CPU states: % idle % user % kernel % iowait % swap
Memory: M real M free M swap in use M swap free
PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND
a K K cpu/ : % top
mpgj M K sleep : % view_server
當時現場數據顯示iowait 值與以前相比大很多 沒有異常進程
sar –d (輸出為實驗室數據僅作格式參考)
SunOS sc Generic_ sunu //
:: device %busy avque r+w/s blks/s avwait avserv
sd
sda
sdb
sdc
sdg
當時現場數據顯示放數據文件的設備 avwait avque blks/s值偏大
第五步 察看數據庫的等待事件
一個大業務量的數據庫如果性能不好的話 一般來說都會有大量的等待事件 上百個等待事件很常見 我通常會按照EVENT進行group
Select count(*) event from v$session_wait where event not in (smon timerpmon timerrdbms ipc messageSQL*Net message from client) group by event order by desc;
輸出結果顯示最多的等待事件是buffer busy waits
進一步分析找出等待的原因
Select count(*) p p p from v$session_wait where event = buffer busy waits group by ppp;
在buffer busy waits等待事件中
P = file#
P = block#
P = id ( 此id對應為等待的原因)
按照ppp group是為了明確buffer busy waits的等待集中在哪些對象上
Metalink對buffer busy waits等待事件的描述有如下一段話
If P shows that the buffer busy wait is waiting for a block read to complete then the blocking session is likely to be waiting on an IO wait (eg: db file sequential read or db file scattered read for the same file# and block#
輸出結果顯示等待分布在多個不同的對象上等待原因為 waiting for a block read to complete進一步分析為IO的問題
如果buffer busy waits等待集中在某個對象上說明有hot block 通過重新rebuild這個對象增加freelist來解決RAC環境增加freelist group
通過以下SQL可以找到具體的object
Select owner segment_name segment_type from dba_extents where file_id=P and P between block_id and block_id+blocks;
PP是上面v$session_wait查出的具體的值
第六步 明確原因找出解決步驟
分析
磁盤的IO流量增加
磁盤的IO等待增加
DB的IO流量沒有增加
DB的IO等待增加
由可以推出有數據庫以外的IO訪問磁盤
察看磁盤配置該VG只存放了數據庫數據文件和數據庫系統文件排除數據文件產生IO的是數據庫系統文件
數據庫系統文件一般來說不會產生IO 有IO讀寫的地方只有log和dump文件
結論ora產生的大量core dump文件堵塞IO
解決辦法
消除ora (應用不改的情況下無法解決)
把dump目錄指向別的VG
讓oracle盡量少的去寫core dump文件
background_core_dump = partial
shadow_core_dump = partial
From:http://tw.wingwit.com/Article/program/Oracle/201311/18969.html