
凌晨兩點被監(jiān)控電話叫醒RAC某個節(jié)點被集群驅逐業(yè)務側報錯蜂擁而至登錄服務器看到CRS資源一片紅。干過Oracle RAC運維的人基本都經歷過這種場面。真正拉開差距的不是你會不會重啟而是你能不能在三五分鐘內判斷該看哪一本日志日志里的哪幾行字符才是關鍵證據(jù)。RAC架構下的故障調查和日志路徑定位就是這樣一件“看著不起眼、做起來要命”的事。這篇文章把我這些年摸出來的RAC日志地圖和排查習慣整理出來適合正在帶RAC項目的DBA也適合剛接觸集群、對一堆日志目錄還沒建立起整體感覺的新手。目標是讓你下次接到故障電話時第一反應不是亂翻目錄而是按層、按節(jié)點、按時間線有序排查。1. 為什么要先建立RAC日志地圖1.1 單實例日志思維為什么不夠用單實例Oracle出問題Alert Log加Trace文件基本就是全部答案最多再看一眼監(jiān)聽日志和操作系統(tǒng)日志半小時內能把來龍去脈理清楚。但RAC完全不是這套玩法。RAC多了一層集群件GIGrid Infrastructure還多了節(jié)點間的心跳網絡、共享存儲、ASM實例、SCAN監(jiān)聽任何一個環(huán)節(jié)出問題都會同時在不同日志里留下片段。你可能會遇到這種情況ocssd.log里記著節(jié)點被驅逐crsd.log里記著資源被關閉實例alert里只留下IPC通信報錯監(jiān)聽日志里全是連接失敗OS messages里還能看到網卡丟包記錄——每本日志都有內容但沒有一本能獨立講完整個故事。所以RAC排障的第一原則是先分層再分節(jié)點。你腦子里必須有一張日志地圖知道故障發(fā)生時應該撲向哪一層、哪一個文件。1.2 RAC日志分層的整體框架我習慣把RAC的日志體系分成五層排障時按這個順序逐層推進層次主要路徑/文件核心內容典型場景集群件層GI$GRID_HOME/log/節(jié)點名/CRS、CSS、EVM、GIPC、mDNS等組件日志節(jié)點驅逐、資源切換、集群無法啟動數(shù)據(jù)庫實例層$ORACLE_BASE/diag/rdbms/db_unique_name/實例名/trace/實例alert、前臺/后臺traceORA錯誤、性能問題、壞塊ASM層$ORACLE_BASE/diag/asm/asm/asm實例名/trace/磁盤組掛載、ASM實例狀態(tài)、I/O錯誤ASM磁盤組dismount、存儲鏈路異常監(jiān)聽層$ORACLE_BASE/diag/tnslsnr/節(jié)點名/連接建立、拒絕、超時業(yè)務連不上、SCAN VIP異常操作系統(tǒng)層/var/log/messages、dmesg、journalctl內存、網絡、存儲、NTP、OOM私網丟包、內存耗盡、時鐘跳變這張地圖不需要死記硬背但至少要形成條件反射看到“節(jié)點驅逐”先想到ocssd和GI alert看到“資源offline”先想到crsd看到“連接失敗”先想到監(jiān)聽日志和網絡層。2. 集群件GI層日志路徑詳解2.1 GI日志的根目錄$GRID_HOME/logGI日志不放在ADR里它獨立放在GI安裝目錄下結構是$GRID_HOME/log/節(jié)點名/GRID_HOME在不同版本里位置不一樣常見的有/u01/app/11.2.0/grid、/u01/app/19.0.0/grid、/u01/app/grid等。你需要先用grid用戶確認環(huán)境變量echo $GRID_HOME echo $ORACLE_HOME注意在grid用戶下ORACLE_HOME通常就是GRID_HOME。好多人排障時用oracle用戶登錄環(huán)境變量指向數(shù)據(jù)庫軟件的ORACLE_HOME結果一個勁兒在數(shù)據(jù)庫軟件目錄里找集群日志自然找不到。這是第一個容易踩的坑。進入$GRID_HOME/log/節(jié)點名/你會看到以下核心文件文件/目錄進程對應關注點alert.log集群級告警所有重大事件的匯總入口crsd/crsd.logCluster Ready Services資源狀態(tài)變遷、OCR訪問cssd/ocssd.logCluster Synchronization Services節(jié)點成員關系、心跳、驅逐evmd/evmd.logEvent Manager事件發(fā)布、FAN通知gipcd/gipcd.logGrid IPC私網通信、網絡心跳mdnsd/mdnsd.logmDNS集群名稱解析、GNS相關ohasd/ohasd.logOracle High Availability Services集群啟動第一階段agent/crsd/各類資源Agentora.*資源啟動/停止/故障轉移2.2 排障首選的集群alert與組件日志集群alert.log是第一個要打開的文件。它不像數(shù)據(jù)庫alert那樣記錄SQL和內部錯誤而是記錄集群層面的關鍵事件節(jié)點加入/離開、資源狀態(tài)變化、OCR切換、ASM磁盤組掛載失敗等。節(jié)點驅逐發(fā)生之前這里通常已經寫了原因相關的提示。ocssd.log是節(jié)點驅逐調查的重頭。CSS進程負責維護節(jié)點成員關系私網心跳斷了、磁盤心跳異常、misscount超時都可能導致一個節(jié)點被另一個節(jié)點強制驅逐。在這個文件里搜這些關鍵詞grep -iE evict|reboot|not reachable|misscount|timeout \ $GRID_HOME/log/$(hostname -s)/cssd/ocssd.log如果看到clssnmPollingThread這類條目基本可以確定是心跳層面的問題接下來去查私網、防火墻、網卡驅動。crsd.log記錄資源層的動作。比如某個節(jié)點的ora.db1.db資源突然offline或者VIP failover到另一節(jié)點都能在這里找到來龍去脈。常見錯誤如File not found、OCR initialization failed等會直接指向OCR或文件權限問題。gipcd.log和mdnsd.log是網絡排查的關鍵配角。私網通信異常時gipcd.log里會出現(xiàn)GIPC_retry、connection timed out之類信息mDNS解析出問題則可能表現(xiàn)為節(jié)點無法加入集群、SCAN VIP解析異常。很多RAC隱患其實早就在這兩個日志里有了苗頭只是平時沒人看。2.3 動態(tài)獲取GI日志位置與配套命令路徑記不準時用命令動態(tài)獲取狀態(tài)信息比死記硬背可靠# 查看集群資源整體狀態(tài) crsctl stat res -t # 查看OCR備份情況 ocrconfig -showbackup # 檢查OCR完整性 ocrcheck # 查看votedisk位置 crsctl query css votedisk另外如果是安裝或升級后集群起不來還要看配置日志目錄$GRID_HOME/cfgtoollogs/比如crsinstall子目錄下的crsinstall_crs_節(jié)點名.log記錄了root.sh執(zhí)行過程中每個步驟的結果。19c安裝腳本卡住時這個文件往往比任何排障日志都直接。3. 數(shù)據(jù)庫實例與ASM層日志路徑3.1 實例ADR結構與alert日志數(shù)據(jù)庫實例的日志由ADRAutomatic Diagnostic Repository管理核心路徑是$ORACLE_BASE/diag/rdbms/db_unique_name/實例名/trace/alert_實例名.log以ORACLE_BASE/u01/app/oracle、庫名orcl、實例orcl1為例完整路徑是tail -f /u01/app/oracle/diag/rdbms/orcl/orcl1/trace/alert_orcl1.log注意db_unique_name和實例名不一定相同RAC里實例名一般是orcl1、orcl2這種帶節(jié)點編號的而db_unique_name就是數(shù)據(jù)庫本身的名字。別拿實例名去匹配目錄名要用adrci確認。最快的確認方式是用SQL直接查SELECT name, value FROM v$diag_info;ADR Base那一行就是$ORACLE_BASEDiag Trace那一行就是trace目錄。也可以命令行下用adrciadrci adrci show homes adrci set home diag/rdbms/orcl/orcl1 adrci show alert -tail 50老系統(tǒng)10g、11.1沒有完整ADR實例日志在background_dump_dest和user_dump_dest指向的目錄一般可以在$ORACLE_HOME/rdbms/log附近找到。如果你接手的是老版本RAC先show parameter dump_dest確認一下別再按11.2以后的路徑找。3.2 ASM實例與監(jiān)聽日志ASM實例的日志也在ADR下結構類似$ORACLE_BASE/diag/asm/asm/asm1/trace/alert_asm1.log注意ASM實例名一般叫ASM1、ASM2目錄名里帶加號。ASM disk group dismount、ASM實例異常重啟、I/O錯誤都從這本alert看起。比如ORA-15063表示ASM無法定位磁盤ORA-15032表示磁盤組操作失敗這些錯誤會同時出現(xiàn)在ASM alert和OCR/集群日志里需要交叉印證。這里有個隱藏坑ASM和數(shù)據(jù)庫的ORACLE_BASE可能不是同一個。如果grid軟件和oracle軟件分開安裝ASM的$ORACLE_BASE通常是grid的路徑比如/u01/app/grid而數(shù)據(jù)庫實例的$ORACLE_BASE才是/u01/app/oracle。用oracle用戶登錄后直接按/u01/app/oracle找ASM日志必然撲空。建議在grid用戶下執(zhí)行echo $ORACLE_BASE再看。監(jiān)聽日志也在ADR體系里但是獨立的一類$ORACLE_BASE/diag/tnslsnr/節(jié)點名/listener/trace/listener.logRAC還有SCAN監(jiān)聽對應目錄$ORACLE_BASE/diag/tnslsnr/節(jié)點名/listener_scan1/trace/listener_scan1.log如果是老版本監(jiān)聽日志可能在$ORACLE_HOME/network/log/。快速確認方法lsnrctl show log_directory3.3 從alert到trace的推導線索實例alert.log里記錄ORA錯誤只是一個起點真正的細節(jié)都在對應的trace文件里??吹絆RA-600、ORA-3137這類錯誤時alert里通常會標注類似Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_ora_12345.trc的路徑直接打開這個trace文件。排查SQL性能或存儲過程問題時也可以主動制造trace。比如ALTER SESSION SET EVENTS 10046 trace name context forever, level 12; -- 執(zhí)行目標SQL ALTER SESSION SET EVENTS 10046 trace name context off;生成的trace文件會帶著會話ID出現(xiàn)在實例trace目錄里。RAC節(jié)點間負載均衡時要先確認會話落在了哪個實例再去對應節(jié)點的trace目錄找文件。4. 操作系統(tǒng)層日志與跨節(jié)點排查思路4.1 系統(tǒng)日志里藏著RAC的“前傳”很多RAC故障的根因并不在Oracle層而在操作系統(tǒng)。最常見的就是私網網卡問題、內存不足觸發(fā)OOM killer、存儲鏈路超時、NTP時鐘跳變。這些都在系統(tǒng)日志里有記錄。Linux環(huán)境優(yōu)先級最高的是/var/log/messages排障時重點搜以下關鍵詞grep -iE out of memory|oom-killer|network|link down|NIC|ntp|time step /var/log/messages尤其要注意的是RAC節(jié)點被驅逐很多時候是“果”不是“因”。比如某節(jié)點內存耗盡觸發(fā)OOM導致CSS進程被殺繼而整個節(jié)點被集群驅逐。這種場景下如果只盯著ocssd.log看你會一直糾結“為什么心跳會斷”而實際上OS日志早就告訴你原因了。另外dmesg -T也是快速排查內核級問題的工具特別是存儲多路徑和網卡收包異常dmesg -T | grep -iE error|fail|timeout|scsi|eth4.2 RAC對時鐘同步的敏感與日志佐證RAC對節(jié)點間時鐘偏差非常敏感。集群內時間不同步輕則日志時間線混亂重則影響事務一致性判斷甚至誘發(fā)節(jié)點驅逐。19c環(huán)境檢查NTP/chrony狀態(tài)timedatectl chronyc sources -v如果OS日志里能看到類似時鐘跳變、time step的信息就要高度懷疑集群故障與時鐘漂移有關。而且時鐘不一致會直接影響你跨節(jié)點排查時的判斷——同一個事件在兩個節(jié)點日志里的時間戳不一樣會讓人誤以為事件順序有問題。所以跨節(jié)點排查前第一件事就是對兩邊的date輸出。4.3 跨節(jié)點時間線對照排查法RAC排障不能只看單個節(jié)點尤其節(jié)點驅逐類問題必須同時拉出兩個甚至所有節(jié)點的關鍵日志按時間排列。我常用的做法是把每個節(jié)點的關鍵事件抓出來統(tǒng)一放到一個文件里排序for node in node1 node2; do ssh $node grep -iE evict|reboot|error|alert \ $GRID_HOME/log/$node/alert.log | sed s/^/[$node] / done | sort這樣能快速看出節(jié)點A在幾點幾分開始心跳異常節(jié)點B在幾點幾分發(fā)起驅逐節(jié)點A在幾點幾分才寫實例alert。時間線一對齊因果鏈就出來了。這一步看起來簡單但很多人排障時容易忽略導致在單個節(jié)點的日志里反復打轉。5. 典型故障場景的日志速查與排查路線5.1 節(jié)點驅逐先看ocssd還是先看GI alert節(jié)點驅逐是RAC最典型、也最讓人頭疼的故障。我的排查順序是打開GI alert.log看驅逐前后的集群事件描述通常能拿到最粗的定位方向。打開ocssd.log搜evict、not reachable、misscount等關鍵詞確認是私網心跳問題還是磁盤心跳問題。打開OS messages確認網絡、內存、存儲有沒有異常記錄。回到數(shù)據(jù)庫alert看實例退出的最后動作。這里有個常見誤區(qū)一上來就翻數(shù)據(jù)庫alert。數(shù)據(jù)庫實例只是集群的“被管理者”它往往是被動退出日志里沒有根因。根因大概率在集群層或OS層。5.2 CRS資源異常與OCR故障如果crsctl stat res -t看到資源反復offline、啟動失敗或處于UNKNOWN狀態(tài)處理路徑是打開crsd.logtail -200 $GRID_HOME/log/$(hostname -s)/crsd/crsd.log搜索關鍵詞error、failed、ocr、permission、cannot。OCR相關故障比較隱蔽。OCR文件損壞或無法同步時crsd.log里會出現(xiàn)OCR讀取失敗的信息。先用ocrcheck確認OCR完整性再用ocrconfig -showbackup看自動備份。OCR自動備份默認放在$GRID_HOME/cdata/節(jié)點名/下比如ls -l $GRID_HOME/cdata/$(hostname -s)/如果OCR真的出了問題可以用最近的備份恢復。需要提醒的是OCR備份文件屬于集群元數(shù)據(jù)日常巡檢時最好納入備份監(jiān)控不要等故障了才發(fā)現(xiàn)備份都過期了。5.3 監(jiān)聽異常業(yè)務連不上的第一現(xiàn)場RAC環(huán)境業(yè)務連接失敗時很多人第一反應是查應用、查防火墻其實應該先看監(jiān)聽日志。連接失敗、超時、拒絕都會在listener.log里留下明確記錄。tail -200 $ORACLE_BASE/diag/tnslsnr/$(hostname -s)/listener/trace/listener.log常見錯誤TNS-12537 TNS-12560監(jiān)聽器自身異?;蚓W絡斷開。TNS-12514服務名沒有注冊可能要看實例是否注冊到監(jiān)聽。Connection timeout可能涉及防火墻或私網質量。如果是SCAN連接失敗除了看SCAN監(jiān)聽日志還要檢查DNS解析是否正常。SCAN VIP對應的域名解析結果必須包含所有節(jié)點DNS只返回一個IP往往會導致單點故障。5.4 ASM磁盤組與實例故障ASM磁盤組dismount、ASM實例異常、存儲鏈路故障這三者經常串在一起。排查順序是ASM alert日志比如alert_asm1.log搜ORA-15063、dismount、I/O error。ASM實例trace目錄確認具體是哪塊磁盤、哪個ASM盤失敗。操作系統(tǒng)存儲層日志dmesg和/var/log/messages里搜multipath、io error、timeout判斷是HBA卡、光纖線還是存儲設備問題。實例啟動失敗時數(shù)據(jù)庫alert里通常能看到ORA-29701cluster無法識別實例、ORA-29740實例心跳失敗之類錯誤這些錯誤要和集群日志配合著看單看任何一本都不完整。5.5 常見故障日志速查表故障現(xiàn)象優(yōu)先查看日志關鍵搜索詞輔助日志節(jié)點驅逐GI alert ocssd.logevict, not reachable, misscountOS messages, gipcd.logCRS資源offlinecrsd.logerror, failed, OCRagent/crsd下日志OCR損壞ocrcheck crsd.logOCR, checksum, format$GRID_HOME/cdata備份監(jiān)聽連接失敗listener.log / scan監(jiān)聽日志TNS-12537, TNS-12514, timeout實例注冊狀態(tài)ASM磁盤組dismountASM alertORA-15063, dismount, I/O errordmesg, multipath日志實例啟動失敗實例alert traceORA-29701, ORA-29740crsd.log, OS messages6. 我在實際排障中用到的幾個實用技巧6.1 日志膨脹與磁盤空間檢查要養(yǎng)成肌肉記憶排障過程中最容易忽略的其實是磁盤空間。$GRID_HOME/log、$ORACLE_BASE/diag都是日志增長大戶。crsd.log長時間不清理漲到幾個GB很常見實例alert和trace文件在故障發(fā)生后會瞬間暴漲。如果/u01被日志塞滿輕則Oracle進程報錯重則整個集群異常雪上加霜。我的習慣是任何RAC排查開始前先執(zhí)行一條df -h確認關鍵分區(qū)剩余空間。這浪費不了半分鐘但能避免后期無法生成trace文件、無法寫dump文件的窘境。日常管理中ADR部分可以利用adrci設置保留策略adrci set home diag/rdbms/orcl/orcl1 adrci purge -age 43200 -type trace43200是分鐘數(shù)相當于30天。GI日志不在ADR管理范圍內需要靠腳本定期歸檔清理。注意不要直接rm正在被進程寫入的日志文件容易造成文件句柄懸空、空間無法釋放。正確做法是先把日志mv走再配合進程或維護窗口處理。6.2 調整組件日志級別的正確姿勢一般不需要動日志級別默認級別足夠日常排查。但如果某些問題復現(xiàn)頻率低、線索模糊可以針對組件臨時調高日志級別crsctl set log level 3 cssd調高后會記錄更細的CSS交互過程對定位心跳類問題有幫助。但注意日志級別調高意味著IO開銷增大、日志量暴增高峰期慎用。排查結束后記得調回原級別否則日志可能以極快速度膨脹。6.3 疑難問題記得收集診斷包遇到自己搞不定、需要求助的場景別手動打包一堆日志直接用官方工具11.2及以后版本可以用diagcollection.sh$GRID_HOME/bin/diagcollection.sh --collect12.2以后更推薦TFA$GRID_HOME/bin/tfactl diagcollect -type daily -srdcTFA會把GI日志、數(shù)據(jù)庫日志、OS日志、網絡配置等匯總成一個壓縮包并自動帶上時間戳。給原廠support提SR時這個包比你自己零散截取的日志有價值得多。排障經驗豐富的人未必每類問題都能獨立解決但懂得在合適的時機收集完整證據(jù)鏈是專業(yè)DBA的重要素質。6.4 我個人的排查習慣最后分享一個自己的習慣不一定適合所有人但實測多次都很穩(wěn)接到RAC故障報告后不急著看alert也不急著重啟先花兩分鐘做三件事——df -h看磁盤、date確認本機時間、crsctl stat res -t看資源全景。然后才打開GI alert順著時間線往下翻。這三件事解決的是“方向”問題。方向對了后續(xù)看ocssd、crsd、實例日志時內心已經有一個基本判斷。方向錯了可能在某個組件的trace文件里翻一晚上最后一查是磁盤滿了或時間漂移。RAC排障不是拼手速是拼誰的地圖更清晰、誰更早鎖定層次。日志路徑從來不是背出來的而是在一次次故障現(xiàn)場練出來的。