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

mysqld_safe 啟動腳本源碼深度解析:流程、技巧與 Shell 編程精華

     編輯:MySQL 資料庫相關知識

前言

閱讀 mysqld_safe 腳本不僅能掌握 MySQL 啟動全流程(目錄尋找、配置解析、進程啟動),更是學習 Shell 編程的優秀教材:變量解析、sed 轉義、進程優先級判斷、test 結構廣泛應用。本文基於 MySQL 5.1.45、RHEL AS 4 環境,梳理核心邏輯與關鍵技巧。

環境基線

MySQL Base: /usr/local/mysql3306
Config Dir: /usr/local/mysql3306/etc
Data Dir:   /usr/local/mysql3306/data

核心流程架構

1. 變量初始化與信號處理

KILL_MYSQLD=1          # 是否清理殘留進程
MYSQLD=                # mysqld 程序名
niceness=0             # 調度優先級
logging=init           # 日誌狀態:init/file/syslog
want_syslog=0          # 是否使用 syslog
user='mysql'           # --user 參數值
trap '' 1 2 3 15       # 忽略 SIGHUP/SIGINT/SIGQUIT/SIGTERM
umask 007              # 預設權限 770

2. 參數解析三階段

函數 parse_arguments() 支援三種輸入來源,按優先級疊加:

  1. 配置文件 [mysqld]、[server]:--loose-verbose 過濾未知選項
  2. 配置文件 [mysqld_safe]、[safe_mysqld]
  3. 命令列參數 $@:最高優先級覆蓋前兩階段

關鍵技巧:SET_USER=2 標記位追蹤 --user 是否已配置,避免重複賦值。

3. 目錄自動發現邏輯

  • Base Dir:優先 MY_BASEDIR_VERSION,其次當前目錄 errmsg.sys,最後編譯時預設 /usr/local/mysql3306
  • Ledir (mysqld 目錄):依序檢查 libexec/、bin/
  • Datadir:優先 $BASEDIR/data/mysql,其次 $BASEDIR/var/mysql,最後編譯預設
  • 配置文件衝突處理:同時存在 $BASEDIR/my.cnf 與 $DATADIR/my.cnf 時優先前者並警告

4. 日誌系統設計

三種模式切換:

  • init:僅控制台輸出
  • file:寫入 --log-error 指定文件(自動補 .err 後綴)
  • syslog:透過 logger 傳送至系統日誌,標籤含 mysqld_safe/mysqld

核心函數 log_generic() 統一格式:YYMMDD HH:MM:SS mysqld_safe msg。

5. 進程優先級智能調整

精妙邏輯:測試 nohup nice 與直接 nice 的優先級差異,若 nohup 導致優先級降低(數值變大),自動補償調整 niceness 值,確保 mysqld 不會因 nohup 而被降級調度。

normal_niceness=`nice`
nohup_niceness=`nohup nice 2>/dev/null`
nice_value_diff=$((nohup_niceness - normal_niceness))
if [ $nice_value_diff -gt 0 ]; then
    niceness=$((niceness - nice_value_diff))
    NOHUP_NICENESS="nice -$niceness nohup"
fi

6. 進程監護主循環

while true; do
    rm -f "$socket_file" "$pid_file"
    eval_log_error "$cmd"   # 啟動 mysqld
    if [ ! -f "$pid_file" ]; then break; fi  # 啟動失敗退出

    # 清理多餘 mysqld_safe 進程
    if [ $KILL_MYSQLD -eq 1 ]; then
        num=$(ps xaww | grep -c "pid-file=$pid_file")
        for each extra process; do kill -9 $pid; done
    fi
    log_notice "mysqld restarted"
done
  • 每次重啟前清理 socket 與 pid 文件
  • eval_log_error 根據日誌模式包裝命令(重導向或管道至 logger)
  • 檢測多餘 mysqld 進程並強制清理,防止分身

Shell 編程精華摘錄

技巧代碼片段用途
安全路徑查找my_which() 遍歷 $PATH,IFS=: 分割替代 which,可移植
參數值提取val=`echo "$arg" | sed -e "s;--[^=]*=;;"`支援 --key=val 格式解析
字符串轉義shell_quote_string() 非字母數字字符前加反斜線防止 eval 注入
陣列模擬append_arg_to_args() 累積到字符串變量構建最終啟動命令
進程樹掃描ps xaww | grep "pid-file=$pid_file"精準識別屬於本實例的進程

總結

mysqld_safe 展示了生產級 Shell 腳本的嚴謹性:信號屏蔽、權限控制、配置疊加、優先級補償、進程監護、日誌多模式。研讀此腳本對理解 MySQL 運維本質與提升 Shell 技藝雙重受益。

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