首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

/var/log/pacct 巨型文件導致 MySQL 啟動失敗:一個被忽視的系統級故障案例

     編輯:MySQL 資料庫相關知識

線上 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
# 空輸出,進程未啟動

關鍵排查步驟

  1. 暴露啟動腳本輸出**:編輯 mysql.server,將 $bindir/mysqld_safe ... >/dev/null 2>&1 的重定向移除,直接運行腳本。
    File size limit exceeded
    nohup: failed to run command ‘...’: File too large
    明確提示 **文件大小超限**。
  2. 檢查數據目錄與日誌**:ls -lh /data/mysql/ 最大文件僅幾百 MB,ulimit -a 顯示 file size (blocks) unlimited,**進程級無限制**。
  3. 全盤掃描大文件**:
    find / -type f -size +2048000k 2>/dev/null
    /var/log/pacct  2.1G
    定位到 /var/log/pacct (進程記賬日誌)。
  4. 根因確認**:運維啟用了 accton 進程記賬,但**未配置日誌輪轉**,文件無限增長至 2GB+。mysqld_safe 腳本使用 nohup 啟動 mysqld,nohup 內部調用 setrlimit(RLIMIT_FSIZE) 繼承 Shell 的文件大小限制,**若當前目錄存在超限文件,某些系統實現會導致 nohup 直接拒絕啟動子進程** (Linux 內核/glibc 版本相關行為差異)。
  5. 緊急恢復**:
    > /var/log/pacct  # 清空文件 (保留 inode,不影響 accton 進程)
    # 或 mv /var/log/pacct /var/log/pacct.bak && systemctl restart accton
    再次啟動 MySQL,**秒級恢復正常**。

深度剖析:為什麼無關的 pacct 文件能卡住 MySQL?

  • mysqld_safe 通常在數據目錄或 /tmp 下運行。
  • nohup 啟動子進程前會檢查 **當前工作目錄** 或 **標準輸出重定向目標文件** 的大小限制 (歷史 BUG/特性)。
  • 若系統全局 RLIMIT_FSIZE 設置較小 (如 2GB),且 pacct 超限,**nohup 拒絕 fork**,導致 mysqld_safe 判定啟動失敗並退出。**但腳本將輸出重定向到 /dev/null 掩蓋了真實錯誤**。

結論:這是 mysql.server/mysqld_safe **錯誤處理邏輯缺陷** — 應捕獲子進程啟動失敗具體錯誤碼並記錄,而非靜默退出。

預防與最佳實踐

  1. 系統日誌必須輪轉**:/etc/logrotate.d/acct 或 psacct 服務配置 daily/size 100M 輪轉,避免 pacct、sa 等文件無限增長。
  2. 監控關鍵目錄磁盤使用率與大文件**:find /var/log -size +500M 納入巡檢腳本。
  3. 啟動腳本去靜默化**:生產環境 mysql.server 應將輸出導向專用日誌文件 (/var/log/mysql/startup.log) 而非 /dev/null,保留故障現場。
  4. 使用 systemd 管理 MySQL** (CentOS 7+/Ubuntu 16.04+):systemctl start mysqld 由 systemd 直接拉起 mysqld,**繞過 mysqld_safe/nohup**,避免此類 Shell 層級干擾。
  5. ulimit 策略**:在 /etc/security/limits.conf 為 mysql 用戶顯式設置 mysql soft fsize unlimited、mysql hard fsize unlimited,確保進程級無文件大小限制。

舉一反三:其他可能觸發「File size limit exceeded」的場景

  • mysqldump 導出大文件超過 ulimit -f。
  • SELECT ... INTO OUTFILE 寫入大文件。
  • 慢查詢日誌、錯誤日誌、Binlog 無輪轉膨脹超限。
  • 應用層日誌 (Log4j, Logback) 未輪轉寫滿磁盤/超限。

這次故障看似「誤傷」,實則暴露了 **基礎設施監控盲區 (系統日誌無輪轉)** 與 **資料庫啟動腳本脆弱性 (靜默失敗、依賴 nohup 行為)**。運維體系需建立「日誌輪轉合規檢查」與「啟動腳本可觀測性增強」兩項機制,從根源杜絕同類故障。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved