「喂,李總您好!」ios
「小張,快點看看ERP數據庫,應用又打不開了!」sql
「好的,立刻。」數據庫
小張從黑色揹包拿出電腦,連上手機熱點就開始檢查,剛連上數據庫,電話鈴聲又響起來了.....服務器
這樣的場景對於Oracle DBA來講太熟悉了,只要應用一出問題,不論什麼時候,不論何地,老是第一個接到電話,嚴重狀況下會是一輪電話轟炸。session
新手和專家之間遇到此類問題,首先是心態,新手遇到問題內心慌,不知從何下手,膽小粗心,專家由於經驗豐富,每每沉着冷靜、指揮若定、抽絲剝繭、膽大心細,可是經驗這東西就跟吃過的鹽、走過的橋同樣,必須親自多作、多學才能得到。而另一個很是重要的就是診斷思路和輔助腳本,本文講述各類場景下的通用處理思路,分享用到的一些腳本,幫助你們快速定位問題並解決,減小業務的中斷事件,早日成爲專家,升職加薪,迎娶...工具
>>>>查看操做系統負載性能
登上數據庫服務器後,第一個就是經過系統命令確認下CPU、內存、I/O是否異常,每一個系統的命令不同,常見的有top、topas、vmstat、iostat。spa
>>>>查看等待事件操作系統
第二步就是連到數據庫查看活動的等待事件,這是監控、巡檢、診斷數據庫最基本的手段,一般81%的問題均可以經過等待事件初步定爲緣由,它是數據庫運行狀況最直接的體現,以下腳本是查看每一個等待事件的個數、等待時長,並排除了一些常見的IDLE等待事件。debug
--墨天輪 wait_event col event for a45 SELECT inst_id,EVENT, SUM(DECODE(WAIT_TIME, 0, 0, 1)) "Prev", SUM(DECODE(WAIT_TIME, 0, 1, 0)) "Curr", COUNT(*) "Tot" , sum(SECONDS_IN_WAIT) SECONDS_IN_WAIT FROM GV$SESSION_WAIT WHERE event NOT IN ('smon timer','pmon timer','rdbms ipc message','SQL*Net message from client','gcs remote message') AND event NOT LIKE '%idle%' AND event NOT LIKE '%Idle%' AND event NOT LIKE '%Streams AQ%' GROUP BY inst_id,EVENT ORDER BY 1,5 desc;
這裏就須要掌握一些常見異常等待事件的緣由,並造成條件反射,好比library cache lock、read by other session、row cache lock、buffer busy waits、latch:shared pool、gc buffer busy、cursor: pin S on X、direct path read、log file sync、enq: TX - index contention、PX Deq Credit: send blkd、latch free、enq: TX - row lock contention等等,若是異常等待事件的個數和等待時間很長,那麼排查緣由的入口就在這裏。
>>>>根據等待事件查會話
獲得異常等待事件以後,咱們就根據等待事件去查會話詳情,也就是查看哪些會話執行哪些SQL在等待,另外還查出來用戶名和機器名稱,以及是否被阻塞。另外以下腳本可改寫成根據用戶查會話、根據SQL_ID查會話等等。
--墨天輪 session_by_event SELECT /*+rule */ sid, s.serial#, spid, event, sql_id, seconds_in_wait ws, row_wait_obj# obj, s.username, s.machine, BLOCKING_INSTANCE||'.'||blocking_session b_sess FROM v$session s, v$process p WHERE event='&event_name' AND s.paddr = p.addr order by 6;
>>>>查詢某個會話詳情
獲得會話列表以後,能夠根據以下SQL查詢某個會話的詳細信息,如上次個執行的SQL_ID,登陸時間等,該SQL也可改寫成多個。
--墨天輪 session_by_sid SELECT s.sid, s.serial#, spid, event, sql_id, PREV_SQL_ID, seconds_in_wait ws, row_wait_obj# obj, s.username, s.machine, module,blocking_session b_sess,logon_time FROM v$session s, v$process p WHERE sid = '&sid' AND s.paddr = p.addr;
>>>>查詢對象信息
從前面兩個SQL均可以看到會話等待的對象ID,能夠經過以下SQL查詢對象的詳細信息。
--墨天輪 obj_info col OBJECT_NAME for a30 select owner,object_name,subobject_name,object_type from dba_objects where object_id=&oid;
>>>>查詢SQL語句
根據SQL_ID、HASH_VALUE查詢SQL語句。若是v$sqlarea中查不到,能夠嘗試DBA_HIST_SQLTEXT視圖中查詢。
--墨天輪 sql_text select sql_id,SQL_fullTEXT from v$sqlarea where (sql_id='&sqlid' or hash_value=to_number('&hashvale') ) and rownum<2;
關於SQL語句的執行計劃、對象的統計信息、性能診斷、跟蹤SQL等這裏就不展開,後面計劃出一個相似的系列,敬請關注。
>>>>查詢會話阻塞狀況
經過以下SQL查詢某個會話阻塞了多少個會話。
--墨天輪 blocking_sess select count(*),blocking_session from v$session where blocking_session is not null group by blocking_session;
>>>>查詢數據庫的鎖
經過以下SQL查詢某個會話的鎖,有哪些TM、TX鎖,以及會話和鎖關聯查詢的SQL,注意這裏指定了ctime大於100秒,30%的狀況是人爲誤操做鎖表,致使應用SQL被阻塞,沒法運行。
--墨天輪 lock set linesize 180 col username for a15 col owner for a15 col OBJECT_NAME for a30 col SPID for a10 --查詢某個會話的鎖 select /*+rule*/SESSION_ID,OBJECT_ID,ORACLE_USERNAME,OS_USER_NAME,PROCESS, LOCKED_MODE from gv$locked_object where session_id=&sid; --查詢TM、TX鎖 select /*+rule*/* from v$lock where ctime >100 and type in ('TX','TM') order by 3,9; --查詢數據庫中的鎖 select /*+rule*/s.sid,p.spid,l.type,round(max(l.ctime)/60,0) lock_min,s.sql_id,s.USERNAME,b.owner,b.object_type,b.object_name from v$session s, v$process p,v$lock l,v$locked_object o,dba_objects b where o.SESSION_ID=s.sid and s.sid=l.sid and o.OBJECT_ID=b.OBJECT_ID and s.paddr = p.addr and l.ctime >100 and l.type in ('TX','TM','FB') group by s.sid,p.spid,l.type,s.sql_id,s.USERNAME,b.owner,b.object_type,b.object_name order by 9,1,3
>>>>保留現場證據
有的問題可能須要分析很長時間,或者是須要外部人員協助分析,那麼保留現場證據就很是重要了,下面腳本是systemstate dump和hanganalyze步驟,若是有sqlplus沒法登錄的狀況,能夠加-prelim參數。
--systemstate dump sqlplus -prelim / as sysdba oradebug setmypid oradebug unlimit; oradebug dump systemstate 266; --wait for 1 min oradebug dump systemstate 266; --wait for 1 min oradebug dump systemstate 266; oradebug tracefile_name; --hanganalyze oradebug setmypid oradebug unlimit; oradebug dump hanganalyze 3 --wait for 1 min oradebug dump hanganalyze 3 --wait for 1 min oradebug dump hanganalyze 3 oradebug tracefile_name
>>>>殺會話
一般狀況下,初步定爲問題後爲了快速恢復業務,須要去殺掉某些會話,特別是批量殺會話,有時還會直接kill全部LOCAL=NO的進程,再殺會話時必定要檢查確認,更不能在別的節點或者別的服務器上執行。
-墨天輪 kill_sess set line 199 col event format a35 --殺某個SID會話 SELECT /*+ rule */ sid, s.serial#, 'kill -9 '||spid, event, blocking_session b_sess FROM v$session s, v$process p WHERE sid='&sid' AND s.paddr = p.addr order by 1; --根據SQL_ID殺會話 SELECT /*+ rule */ sid, s.serial#, 'kill -9 '||spid, event, blocking_session b_sess FROM v$session s, v$process p WHERE sql_id='&sql_id' AND s.paddr = p.addr order by 1; --根據等待事件殺會話 SELECT /*+ rule */ sid, s.serial#, 'kill -9 '||spid, event, blocking_session b_sess FROM v$session s, v$process p WHERE event='&event' AND s.paddr = p.addr order by 1; --根據用戶殺會話 SELECT /*+ rule */ sid, s.serial#, 'kill -9 '||spid, event, blocking_session b_sess FROM v$session s, v$process p WHERE username='&username' AND s.paddr = p.addr order by 1; --kill全部LOCAL=NO進程 ps -ef|grep LOCAL=NO|grep $ORACLE_SID|grep -v grep|awk '{print $2}' |xargs ki
>>>>重啓大法
tail -f alert_.log alter system checkpoint; alter system switch logfile; shutdown immediate; startu
如須要修改靜態參數、內存等問題,須要重啓數據庫,(不要以爲重啓很LOW,在不少狀況下爲了快速恢復業務常用這個從網吧裏傳出來的絕招),記住千萬不要在這個時候死磕問題緣由、看成課題研究,咱們的首要任務是恢復業務。
>>>>CRT按鈕小技巧
另外介紹一個小技巧,就是把經常使用的腳本整理到SecureCRT的Button Bar中,只須要點一下設置好的button,就至關於直接執行相應的SQL語句,這樣就不用每次粘貼複製執行,或者是把腳本上傳到每一個服務器上。不過不要設置DDL等操做性的button,以避免誤點。
以上就是遇到數據庫問題用到的一些腳本,特別是應用反應慢、卡的狀況,另外建議首先對腳本進行閱讀而後再使用,還能夠根據本身的環境改寫,融會貫通,積累經驗。
我把這些腳本都整理到墨天輪的經常使用腳本中,上面還有許多其餘監控、管理、診斷的工具腳本,你們能夠免費去上面拷貝下載使用。(點擊下方下載便可免費拷貝下載~)
下載網址:cs.enmotech.com/scripts