萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux Crontab 定時修改資料庫日期失效之排查實錄

在 Linux 系統中利用 crontab 排程執行腳本修改資料庫日期,原本以為設定完成即可自動生效,卻發現隔天資料庫日期毫無變化。本文記錄完整的問題重現、排查過程、最終解決方案,以及遺留的兩個核心疑問,供遇到類似情況的系統管理員參考。

問題重現:crontab 設定後不執行

操作環境與步驟

  • 作業系統:Linux(發行版未標註,推測為 RHEL/CentOS 系列)
  • 執行用戶:yz(一般用戶)
  • 排程內容:0 1 * * * chg_date > /home/yz/yz.log(每天凌晨 1 點執行)
  • 編輯方式:crontab -e,以 :wq 存檔離開。

預期與實際結果

預期實際
隔天資料庫日期自動更新資料庫日期維持前一天,chg_date 完全未執行

排查過程:從文獻到實測

階段 1:信任文獻,未重啟服務

根據常見文獻說明:crontab -e 存檔後會寫入 /var/spool/cron/username,crond 守護進程每分鐘掃描 /etc/crontab、/etc/cron.d/、/var/spool/cron/ 變化並自動載入,**無需重啟服務****。因此當時未做進一步測試直接下班。

階段 2:縮短間隔測試 + 重啟服務

隔天發現失效後,修改 crontab 為每 2 分鐘執行一次:

*/2 * * * * chg_date > /home/yz/yz.log

等待數分鐘,資料庫日期仍未更新。隨後嘗試重啟 cron 服務:

/etc/rc.d/init.d/crond restart

結果:依然無效。

階段 3:切換 root 用戶設定 + 重啟服務

同事建議嘗試以 root 身分設定排程,並透過 su 切換用戶執行:

# root 執行 crontab -e
*/2 * * * * (su - yz -c "chg_date" 2>> /home/yz/yz.log)

等待數分鐘,**仍無變化**。

階段 4:關鍵突破——再次重啟 crond

抱著試試看心態,再次手動執行:

/etc/rc.d/init.d/crond restart

幾分鐘後,**資料庫日期終於成功更新**,問題解決。

核心發現總結

  1. yz 用戶自建 crontab 完全不生效,即使 /var/spool/cron/yz 確實存在對應定義。
  2. root 用戶設定 + su 切換用戶 同樣需要 重啟 crond 服務 才能生效。
  3. 單純修改 crontab 檔案(無論哪個用戶),在本案例環境中**不會自動被 crond 拾取**。

遺留疑問:尋求社群解答

  1. 為什麼 yz 用戶下建立的 crontab 不生效?
    已確認 /var/spool/cron/yz 檔案存在且內容正確,權限為 600,擁有者為 yz。crond 日誌(/var/log/cron)無任何錯誤訊息,亦無執行紀錄。
  2. 為什麼必須重啟 crond 服務?
    多數同事反映在相同發行版下,crontab -e 存檔即刻生效,無需重啟。本環境是否存在特殊配置(如 SELinux 策略、cron.allow/deny 限制、pam 模組設定)導致 inotify 監聽失效?

後續建議驗證方向

1. 檢查 crond 運行狀態與日誌

systemctl status crond        # 或 service crond status
tail -f /var/log/cron         # 觀察是否有 RELOAD 或錯誤訊息

2. 驗證 crond 的 inotify 監聽

strace -p $(pidof crond) -e trace=inotify_add_watch,inotify_rm_watch

3. 檢查存取控制檔案

cat /etc/cron.allow   # 若存在,僅名單內用戶可用 crontab
cat /etc/cron.deny    # 若存在,名單內用戶被禁止
# 若兩者皆不存在,預設所有用戶可用

4. SELinux 環境下的權限問題

ls -Z /var/spool/cron/yz
# 確認 context 為 system_cron_spool_t
restorecon -v /var/spool/cron/yz  # 修復 context

5. 測試簡單指令排除腳本問題

# yz 用戶 crontab 寫入
*/2 * * * * /bin/date >> /home/yz/test_cron.log
# 觀察是否產生日誌

最佳實踐建議

  • 生產環境修改 crontab 後,建議執行 systemctl reload crond 或 service crond reload,確保配置立即生效,避免依賴自動重載機制。
  • 排程腳本務必使用絕對路徑(如 /usr/local/bin/chg_date),並重導向 stdout 與 stderr 至日誌檔便於事後追蹤。
  • 重要排程應加入健康檢查機制(如每次執行寫入 heartbeat 檔案,監控系統定期檢查該檔案 mtime)。
  • 若環境存在多用戶排程需求,考慮集中管理至 /etc/cron.d/ 目錄下獨立檔案,由 root 統一維護,避免用戶級 crontab 權限與環境變數陷阱。
copyright © 萬盛學電腦網 all rights reserved