DBMS_JOBDBA_JOBS 顯示 NEXT_DATE 正常但 LAST_DATE 停留在數天前。手動 DBMS_JOB.RUN(job) 正常。uptime 顯示主機已連續運行 500 天。SELECT job, last_date, last_sec, next_date, next_sec, broken, failures
FROM dba_jobs;
所有 Job BROKEN=N、FAILURES=0,但無實際執行記錄。
CREATE OR REPLACE PROCEDURE pining IS BEGIN NULL; END;
VARIABLE jobno NUMBER; VARIABLE instno NUMBER;
BEGIN
SELECT instance_number INTO :instno FROM v$instance;
DBMS_JOB.SUBMIT(:jobno, 'pining;', TRUNC(SYSDATE+1/288,'MI'), 'TRUNC(SYSDATE+1/288,''MI'')', TRUE, :instno);
END;
測試 Job 同樣不自動執行,手動 RUN 正常 → 排除 Job 定義邏輯問題,鎖定排程器進程 (CJQ0) 異常。
ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 0; -- 等 2-3 分鐘殺掉 CJQ0
ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 5; -- PMON 重啟 CJQ0
Alert Log 確認 Restarting dead background process CJQ0,但 Job 仍不執行。再次調整參數導致 CJQ0 反覆死亡。
離峰時段 Shutdown/Startup,CJQ0 正常啟動,但 Job 依然不跑 → 非進程存活問題,涉及核心計時邏輯。
Bug: slgcsf()/slgcs() on Solaris stops incrementing after ~497 days uptime.
Root: gethrtime() returns nanoseconds > 42949672950000000 (2^32 * 10^4?)
slgcs() stays at 0xFFFFFFFF.
Impact: kkJSsrh() uses "now = slgcs()" to compare timestamps.
After 497 days, "now - last_run" always 0 → Job scheduler thinks no time elapsed.
Fix: Included in 9.2.0.6 Patchset (Solaris 9.2.0.6 尚未釋出時)。
bash$ uptime
10:00pm up 500 day(s), 14:57, 1 user, load average: 1.31, 1.09, 1.08
完美吻合 497 天臨界點。
gethrtime() 計數器。uptime 或 V$TIMER.HSECS 異常停滯,接近 490 天發出告警。SQL> SELECT job, last_date, last_sec, next_date, next_sec FROM user_jobs;
JOB LAST_DATE LAST_SEC NEXT_DATE NEXT_SEC
70 26-NOV-04 09:21:04 26-NOV-04 09:26:00
SQL> / (5分鐘後)
JOB LAST_DATE LAST_SEC NEXT_DATE NEXT_SEC
70 26-NOV-04 09:26:01 26-NOV-04 09:31:00
SQL> SELECT * FROM v$timer;
HSECS 3388153 (持續遞增,正常)
Job 恢復正常排程執行,V$TIMER 計數器正常遞增。
slgcs() (System Layer Get CentiSeconds) 封裝 OS gethrtime() (高解析度時間),轉換為百分秒供內核使用。kkJSsrh() (Job Scheduler 主循環) 週期性呼叫 now = slgcs(),比對 last_run_time 判斷 Job 是否到期。4,294,967,295 約等於 497 天的百分秒數。Solaris gethrtime() 回傳奈秒,轉換邏輯溢位導致 slgcs() 卡在 0xFFFFFFFF。| 教訓 | 行動 |
|---|---|
| 長運行系統隱藏計時器溢位風險 | 定期 Reboot OS (建議 < 180 天) 或升級修補版本 |
| Job 不跑不一定是 Job 壞了 | 檢查 CJQ0 進程、V$TIMER、OS uptime、Alert Log 綜合判斷 |
| 疑難雜症大膽懷疑 Bug | Metalink/MOS 搜尋關鍵字 (uptime, slgcs, job queue, 497 days) |
| 升級前驗證 Patchset 釋出狀態 | 確認目標平台已有修補版本再規劃升級 |
這起「497 天 Job 罷工」案例,揭示了作業系統層面計時器溢位如何穿透資料庫內核影響核心排程功能。它提醒我們:基礎設施層 (OS/Hardware) 的長期運行狀態,同樣是資料庫穩定性的關鍵變數。建立「OS 定期重啟/升級」與「資料庫關鍵指標監控 (V$TIMER, CJQ0 狀態)」雙重防線,才能避免類似「時間炸彈」在關鍵時刻引爆。