一套穩定運行一年的 Oracle 11g 應用系統突然無法連接,報錯 `ORA-12537: TNS:connection closed`、`ORA-609: TNS:protocol adapter error`。監聽狀態查詢卡頓 10 分鐘,`tnsping` 無響應,但本地 `sqlplus` 登錄正常。本文通過完整日志分析、進程追蹤、文件系統檢查,定位根因:**監聽日志文件 `listener.log` 達到 4GB 文件系統限制,無法寫入導致監聽進程阻塞,拒絕新連接**。
Fatal NI connect error 12537, connecting to: (LOCAL=NO) VERSION INFORMATION: TNS for 64-bit Windows: Version 11.2.0.1.0 - Production ... Tns error struct: ns main err code: 12537 TNS-12537: TNS:connection closed ns secondary err code: 12560 TNS-12560: TNS:protocol adapter error nt main err code: 0 nt secondary err code: 0 nt OS err code: 0 opiodr aborting process unknown ospid (6052) as a result of ORA-609
TNS-12560: TNS:protocol adapter error TNS-00530: Protocol adapter error 64-bit Windows Error: 53: Unknown error TNS-12518: TNS:listener could not hand off client connection TNS-12571: TNS:packet writer failure TNS-12560: TNS:protocol adapter error TNS-00530: Protocol adapter error 64-bit Windows Error: 54: Unknown error
# 1. 停止監聽 (可選,監聽會自動重建日志文件) lsnrctl stop # 2. 刪除或移動舊日志 (建議歸檔壓縮保留) mv $ORACLE_HOME/network/log/listener.log $ORACLE_HOME/network/log/listener.log.20150616 gzip $ORACLE_HOME/network/log/listener.log.20150616 # 3. 啟動監聽 lsnrctl start # 4. 驗證 lsnrctl status # 秒級返回 tnsping# 正常響應 # 遠程應用恢復連接
-- 修改 listener.ora,添加/修改以下參數
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = your_host)(PORT = 1521))
)
)
-- 日志控制參數 (11g 引入 ADR 自動診斷庫,但傳統 listener.log 仍受控於以下參數)
LOG_DIRECTORY_LISTENER = /u01/app/oracle/diag/tnslsnr/host/listener/alert -- 建議指向 ADR 目錄 (無 4G 限制)
LOG_FILE_LISTENER = listener.log
LOGGING_LISTENER = ON
-- 關鍵:啟用自動輪轉 (11.2.0.2+)
LOGGING_LISTENER = ON
LOG_FILE_NUM_LISTENER = 10 -- 保留 10 個輪轉文件
LOG_FILE_SIZE_LISTENER = 100M -- 每文件最大 100MB (觸發輪轉)
-- 或者完全切換到 ADR (Automatic Diagnostic Repository) 管理
-- ADR 基礎目錄: DIAGNOSTIC_DEST (默認 $ORACLE_BASE)
-- 監聽 ADR Home: $ADR_BASE/diag/tnslsnr//
-- ADR 內部自動管理 alert/log/trace,無單文件大小限制,支援自動清理 (SHORTP_POLICY/LOG_POLICY)
-- 確保 listener.ora 未硬編碼 LOG_FILE_LISTENER 到非 ADR 路徑
| 文件 | 路徑 | 風險 | 管理策略 |
|---|---|---|---|
| 監聽日志 | $ORACLE_HOME/network/log/listener.log | 4G 限制阻塞新連接 | 遷移至 ADR / 設置 LOG_FILE_SIZE/LOG_FILE_NUM |
| SQLNET 日志 | $ORACLE_HOME/network/log/sqlnet.log | 同樣 4G 限制,導致客戶端連接慢/失敗 | 遷移至 ADR / 關閉不必要的 SQLNET 日志 (`DIAG_ADR_ENABLED=OFF`) |
| Alert 日志 | $ORACLE_BASE/diag/rdbms/ | ADR 管理通常無問題,但極端錯誤風暴可撐爆磁盤 | 監控磁盤使用率、設置 `DIAGNOSTIC_DEST` 獨立磁盤 |
| Trace 文件 | $ORACLE_BASE/diag/.../trace/*.trc | 事件 10046/10053 大量追蹤撐爆磁盤 | 用畢即關、定期清理、限制追蹤範圍 |
| 核心轉儲 | $ORACLE_BASE/diag/.../cdump/ | 實例崩潰生成 GB 級核心文件 | 監控磁盤、配置 `CORE_DUMP_DEST` 獨立分區 |
| 審計文件 | $ORACLE_BASE/admin/ | 強制審計 (AUDIT_TRAIL=OS) 產生海量小文件,耗盡 inode | 遷移至資料庫審計 (AUDIT_TRAIL=DB/DB,EXTENDED)、定期歸檔清理 |
find $ORACLE_BASE/diag -name "*.trc" -mtime +30 -delete
find $ORACLE_BASE/diag -name "*.trm" -mtime +30 -delete
find $ORACLE_HOME/network/log -name "*.log" -size +500M -exec mv {} {}.old \; -exec gzip {}.old \;
這個「小文件大故障」案例深刻警示:**日志文件無限增長是定時炸彈**。現代 Oracle 運維必須將日志管理納入基礎設施自動化體系,利用 ADR 原生能力、文件系統配額、監控告警、定期清理,將風險消滅在萌芽狀態。細節決定成敗,日志管理不容忽視。