SHOW DATABASES; 驗證 SQL 層響應。#!/bin/bash
# mysql_guard.sh - MySQL 存活檢測與自動恢復
# 依賴: nmap, mysql client, mysqld_safe
# 部署: crontab -e */5 * * * * /path/mysql_guard.sh >> /var/log/mysql_guard.log 2>&1
set -euo pipefail
# ========== 配置區 ==========
MYSQL_HOST="localhost"
MYSQL_PORT="3306"
MYSQL_USER="monitor_user" # 建議專用監控帳號
MYSQL_PASS="StrongPass123!"
MYSQL_BASE="/usr/local/mysql" # MySQL 安裝根目錄
MYSQLD_SAFE="${MYSQL_BASE}/bin/mysqld_safe"
MYSQL_BIN="${MYSQL_BASE}/bin/mysql"
CONNECT_TIMEOUT=5 # 連線超時秒數
LOG_FILE="/var/log/mysql_guard.log"
PID_FILE="${MYSQL_BASE}/data/$(hostname).pid"
# ============================
log() { echo "[$(date '+%F %T')] $*" | tee -a "${LOG_FILE}"; }
# 1. 端口掃描 (nmap 快速、無需完整連線)
if nmap -p "${MYSQL_PORT}" "${MYSQL_HOST}" | grep -q "${MYSQL_PORT}/open"; then
log "Port ${MYSQL_PORT} is OPEN. Proceeding to SQL layer check..."
# 2. SQL 層健康檢查 (帶超時、只查元數據)
if "${MYSQL_BIN}" -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" \
-u"${MYSQL_USER}" -p"${MYSQL_PASS}" \
--connect-timeout="${CONNECT_TIMEOUT}" \
-e "SHOW DATABASES;" >/dev/null 2>&1; then
log "MySQL is HEALTHY. No action needed."
exit 0
else
log "WARNING: Port open but SQL layer UNRESPONSIVE. Initiating FORCE RESTART..."
fi
else
log "WARNING: Port ${MYSQL_PORT} CLOSED. MySQL process likely DOWN. Initiating START..."
fi
# 3. 統一強制重啟流程 (殺進程 → 清理 → 啟動)
log "Stopping any residual MySQL processes..."
# 精準殺進程:僅殺 mysqld 主進程,避免誤殺備份/客戶端進程
pkill -f "${MYSQL_BASE}/bin/mysqld" 2>/dev/null || true
sleep 2
# 雙重保險:殘留進程用 SIGKILL
pkill -9 -f "${MYSQL_BASE}/bin/mysqld" 2>/dev/null || true
# 清理可能殘留的 socket/鎖文件
rm -f "${MYSQL_BASE}/data/mysql.sock" "${MYSQL_BASE}/data/mysql.sock.lock" 2>/dev/null
log "Starting MySQL via mysqld_safe..."
# nohup + & 確保脫離終端;輸出導向 /dev/null 避免 cron 郵件堵塞
nohup "${MYSQLD_SAFE}" --user=mysql >/dev/null 2>&1 &
# 4. 啟動後驗證 (給 10 秒緩衝)
sleep 10
if nmap -p "${MYSQL_PORT}" "${MYSQL_HOST}" | grep -q "${MYSQL_PORT}/open"; then
if "${MYSQL_BIN}" -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" \
-u"${MYSQL_USER}" -p"${MYSQL_PASS}" \
--connect-timeout="${CONNECT_TIMEOUT}" \
-e "SHOW DATABASES;" >/dev/null 2>&1; then
log "SUCCESS: MySQL RESTARTED and VERIFIED healthy."
exit 0
else
log "CRITICAL: Process started but SQL layer STILL UNRESPONSIVE!"
exit 1
fi
else
log "CRITICAL: MySQL FAILED to start (port still closed)."
exit 1
fi
| 工具 | 優點 | 缺點 | 適用性 |
|---|---|---|---|
| nmap | 主動探測、跨主機、狀態機標準化、腳本友好 | 需安裝、掃描稍慢 (ms 級) | ✅ 最佳:腳本化、遠程檢測 |
| netstat/ss | 系統內建、顯示進程 PID | 需 root 權限看完整資訊、解析麻煩 | 次選:本機檢測 |
| lsof -i:3306 | 直接顯示進程與 FD | 需 root、輸出格式不穩定 | 輔助:排查佔用 |
| mysqladmin ping | 應用層語義檢測 | 需帳號密碼、無法區分端口開但服務掛 | 配合:二次驗證 |
mysqladmin shutdown 需要 SQL 層響應,但故障時 SQL 層往往已掛死。mysqld_safe 監控腳本會嘗試優雅關閉,但掛死進程不響應信號。CREATE USER 'monitor_user'@'localhost' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT ON *.* TO 'monitor_user'@'localhost'; -- 僅需 SELECT 執行 SHOW DATABASES
FLUSH PRIVILEGES;
MYSQL_BASE/port。mysql_up 1/0,接入監控體系。yum install -y nmap / apt install -y nmapchmod +x mysql_guard.sh./mysql_guard.sh*/5 * * * * /opt/scripts/mysql_guard.sh/var/log/mysql_guard.log 確認無誤報這個腳本體現了「檢測→判斷→分級處理→驗證閉環」的運維自動化核心思想。將其納入基礎設施代碼庫,配合監控告警體系,能將 MySQL 因進程掛死導致的業務中斷時間壓縮到分鐘級甚至秒級。