嘗試在 /etc/my.cnf 的 [mysqld] 或 [mysqld_safe] 區塊設置 log-error=/new/path/error.log,重啟後日誌仍寫入舊路徑 /var/log/mysqld.log。
通過 ps aux | grep mysqld 發現啟動命令行顯式指定了參數:
/bin/sh /usr/bin/mysqld_safe \
--datadir=/data/mysql \
--socket=/var/lib/mysql/mysql.sock \
--log-error=/var/log/mysqld.log \ ← 命令行參數覆蓋配置文件
--pid-file=/var/run/mysqld/mysqld.pid
/usr/libexec/mysqld \
--basedir=/usr \
--datadir=/data/mysql \
--user=mysql \
--pid-file=/var/run/mysqld/mysqld.pid \
--skip-external-locking \
--port=3306 \
--socket=/var/lib/mysql/mysql.sock
命令行參數 > 配置文件 > 編譯默認值,故 my.cnf 設置被忽略。
chkconfig --list 確認服務由 mysqld init 腳本管理/etc/init.d/mysqld 腳本,發現關鍵讀取邏輯:
get_mysql_option mysqld datadir "/var/lib/mysql"
datadir="$result"
get_mysql_option mysqld socket "$datadir/mysql.sock"
socketfile="$result"
get_mysql_option mysqld_safe log-error "/var/log/mysqld.log" ← 這裡有默認值!
errlogfile="$result"
get_mysql_option mysqld_safe pid-file "/var/run/mysqld/mysqld.pid"
mypidfile="$result"
get_mysql_option 函數會優先讀取命令行參數,再讀取 my.cnf,最後用硬編碼默認值編輯 /etc/init.d/mysqld,修改 get_mysql_option 調用的默認值參數:
# 原代碼
get_mysql_option mysqld_safe log-error "/var/log/mysqld.log"
errlogfile="$result"
# 修改為
get_mysql_option mysqld_safe log-error "/data/logs/mysql/error.log"
errlogfile="$result"
同步修改 pid-file、socket 等相關路徑保持一致性。
# 重啟服務
service mysqld restart
# 驗證進程參數
ps aux | grep mysqld
# 應顯示 --log-error=/data/logs/mysql/error.log
# 驗證日誌文件
tail -f /data/logs/mysql/error.log
# 應有新寫入內容
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 修改 init 腳本默認值 | 根治、持久化、符合發行版管理規範 | 需 root、升級包可能覆蓋 | 生產環境標準部署 |
| 在 my.cnf 設置並清空腳本默認值 | 集中配置管理 | 需確保腳本不再硬編碼傳參 | 自定義編譯/非標準部署 |
| systemd 覆蓋 (Override) | 不修改原文件、系統級管理 | 需 systemd 版本、學習成本 | RHEL 7+/CentOS 7+/Ubuntu 16.04+ |
| 直接修改啟動命令 | 快速測試 | 非持久化、重啟失效 | 臨時調試 |
# 創建覆蓋單元
systemctl edit mysqld
# 編輯器中輸入
[Service]
Environment=MYSQLD_OPTS="--log-error=/data/logs/mysql/error.log"
# 重載並重啟
systemctl daemon-reload
systemctl restart mysqld
mkdir -p /data/logs/mysql && chown mysql:mysql /data/logs/mysqllogrotate 避免單文件過大