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

MySQL 狀態檢測自動恢復腳本:nmap 端口掃描、連線驗證、進程重啟、生產環境部署指南

     編輯:MySQL 資料庫相關知識

腳本設計目標

  • 檢測 MySQL 3306 端口是否監聽
  • 驗證實際連線查詢是否正常 (防止假死/阻塞)
  • 異常時自動殺掉殭屍進程並重啟服務
  • 避免誤殺、重啟風暴、日誌記錄可追蹤

完整腳本 /usr/local/bin/mysql_monitor.sh


#!/bin/bash
# MySQL 狀態檢測與自動恢復腳本
# 依賴: nmap, mysql client
# 建議每 1-5 分鐘透過 crontab 執行一次

# 配置區 ----------------------------------------------------
MYSQL_HOST="localhost"
MYSQL_PORT=3306
MYSQL_USER="monitor_user"
MYSQL_PASS="MonitorPass123!"
MYSQL_BASE="/usr/local/mysql"
CHECK_TIMEOUT=5
LOG_FILE="/var/log/mysql_monitor.log"
# -----------------------------------------------------------

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
}

# 1. 檢查端口是否監聽 (nmap 掃描本機)
if /usr/bin/nmap -p ${MYSQL_PORT} ${MYSQL_HOST} | grep -q "${MYSQL_PORT}/tcp open"; then
    log "端口 ${MYSQL_PORT} 正常監聽"
    
    # 2. 驗證實際連線查詢
    if ${MYSQL_BASE}/bin/mysql -u${MYSQL_USER} -p${MYSQL_PASS} \
        --connect-timeout=${CHECK_TIMEOUT} \
        -e "SHOW DATABASES;" > /dev/null 2>&1; then
        log "MySQL 連線查詢正常"
        exit 0
    else
        log "MySQL 連線查詢失敗,嘗試重啟服務"
        
        # 3. 殺掉所有 mysqld 進程 (含殭屍)
        pids=$(/bin/ps aux | grep mysqld | grep -v grep | awk '{print $2}')
        if [ -n "${pids}" ]; then
            log "殺掉進程: ${pids}"
            kill -9 ${pids} 2>/dev/null
            sleep 3
        fi
        
        # 4. 重啟服務
        ${MYSQL_BASE}/bin/mysqld_safe --user=mysql & > /dev/null
        log "MySQL 服務重啟指令已發送"
        
        # 5. 等待啟動並再次驗證
        sleep 10
        if ${MYSQL_BASE}/bin/mysql -u${MYSQL_USER} -p${MYSQL_PASS} \
            --connect-timeout=${CHECK_TIMEOUT} \
            -e "SHOW DATABASES;" > /dev/null 2>&1; then
            log "重啟後 MySQL 服務恢復正常"
        else
            log "重啟後 MySQL 服務仍異常,需人工介入"
        fi
    fi
else
    log "端口 ${MYSQL_PORT} 未監聽,直接啟動服務"
    ${MYSQL_BASE}/bin/mysqld_safe --user=mysql & > /dev/null
    log "MySQL 服務啟動指令已發送"
fi

關鍵設計決策解析

為何用 nmap 而非 netstat/ss?

  • nmap -p 3306 localhost 模擬真實客戶端連線嘗試,驗證防火牆、TCP 堆疊、監聽佇列全鏈路
  • netstat/ss 僅顯示核心狀態,無法檢測「端口開著但不接受連線」的假死狀態

為何殺進程而非 service restart?

  • MySQL 偶發無法正常關閉 (鎖死、檔案描述符洩漏、InnoDB 恢復卡住)
  • service restart 依賴正常關機流程,可能卡住導致重啟失敗
  • kill -9 強制釋放資源,確保乾淨重啟

監控帳號最小權限


CREATE USER 'monitor_user'@'localhost' IDENTIFIED BY 'MonitorPass123!';
GRANT USAGE ON *.* TO 'monitor_user'@'localhost';
FLUSH PRIVILEGES;
# 僅需 USAGE 權限 (連線驗證),無任何資料存取權

部署與運維

Crontab 部署 (每 2 分鐘檢測)


# vim /etc/crontab
*/2 * * * * root /usr/local/bin/mysql_monitor.sh

Systemd 服務化 (更穩健)


# /etc/systemd/system/mysql-monitor.service
[Unit]
Description=MySQL Monitor & Auto Recovery
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mysql_monitor.sh
User=root

# /etc/systemd/system/mysql-monitor.timer
[Unit]
Description=Run MySQL Monitor every 2 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=2min
Persistent=true

[Install]
WantedBy=timers.target

# 啟用
systemctl daemon-reload
systemctl enable --now mysql-monitor.timer

日誌輪轉


# /etc/logrotate.d/mysql_monitor
/var/log/mysql_monitor.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 640 root root
}

進階增強建議

  1. 多節點檢測:主從雙向檢測、延遲監控 (Seconds_Behind_Master)
  2. 告警通知:整合 Telegram/Slack/Email/Webhook,異常即時推送
  3. 健康度評分:連線數、緩衝池命中率、慢查詢、磁碟空間綜合評分
  4. 熔斷機制:連續 N 次重啟失敗 → 停止自動重啟、升級人工介入
  5. 藍綠部署相容:支援多實例、多端口配置陣列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved