線上 MySQL 突然無法啟動:mysql.server start 無任何輸出直接退出,mysqld 進程未拉起。去除啟動腳本輸出重定向後發現核心錯誤:File size limit exceeded。經排查,**系統進程記賬日誌 /var/log/pacct 膨脹至 2GB+,觸發文件大小限制 (ulimit -f) 導致 mysqld_safe 啟動失敗**。本文還原排查全過程並分析腳本邏輯缺陷。
[root@db ~]# service mysql start
Starting MySQL. [ OK ] # 腳本返回成功,但進程實際未存活
[root@db ~]# ps -ef | grep mysqld
# 空輸出,進程未啟動
mysql.server,將 $bindir/mysqld_safe ... >/dev/null 2>&1 的重定向移除,直接運行腳本。
File size limit exceeded
nohup: failed to run command ‘...’: File too large
明確提示 **文件大小超限**。ls -lh /data/mysql/ 最大文件僅幾百 MB,ulimit -a 顯示 file size (blocks) unlimited,**進程級無限制**。find / -type f -size +2048000k 2>/dev/null
/var/log/pacct 2.1G
定位到 /var/log/pacct (進程記賬日誌)。accton 進程記賬,但**未配置日誌輪轉**,文件無限增長至 2GB+。mysqld_safe 腳本使用 nohup 啟動 mysqld,nohup 內部調用 setrlimit(RLIMIT_FSIZE) 繼承 Shell 的文件大小限制,**若當前目錄存在超限文件,某些系統實現會導致 nohup 直接拒絕啟動子進程** (Linux 內核/glibc 版本相關行為差異)。> /var/log/pacct # 清空文件 (保留 inode,不影響 accton 進程)
# 或 mv /var/log/pacct /var/log/pacct.bak && systemctl restart accton
再次啟動 MySQL,**秒級恢復正常**。mysqld_safe 通常在數據目錄或 /tmp 下運行。nohup 啟動子進程前會檢查 **當前工作目錄** 或 **標準輸出重定向目標文件** 的大小限制 (歷史 BUG/特性)。RLIMIT_FSIZE 設置較小 (如 2GB),且 pacct 超限,**nohup 拒絕 fork**,導致 mysqld_safe 判定啟動失敗並退出。**但腳本將輸出重定向到 /dev/null 掩蓋了真實錯誤**。結論:這是 mysql.server/mysqld_safe **錯誤處理邏輯缺陷** — 應捕獲子進程啟動失敗具體錯誤碼並記錄,而非靜默退出。
/etc/logrotate.d/acct 或 psacct 服務配置 daily/size 100M 輪轉,避免 pacct、sa 等文件無限增長。find /var/log -size +500M 納入巡檢腳本。mysql.server 應將輸出導向專用日誌文件 (/var/log/mysql/startup.log) 而非 /dev/null,保留故障現場。systemctl start mysqld 由 systemd 直接拉起 mysqld,**繞過 mysqld_safe/nohup**,避免此類 Shell 層級干擾。/etc/security/limits.conf 為 mysql 用戶顯式設置 mysql soft fsize unlimited、mysql hard fsize unlimited,確保進程級無文件大小限制。mysqldump 導出大文件超過 ulimit -f。SELECT ... INTO OUTFILE 寫入大文件。這次故障看似「誤傷」,實則暴露了 **基礎設施監控盲區 (系統日誌無輪轉)** 與 **資料庫啟動腳本脆弱性 (靜默失敗、依賴 nohup 行為)**。運維體系需建立「日誌輪轉合規檢查」與「啟動腳本可觀測性增強」兩項機制,從根源杜絕同類故障。