線上 MySQL 因架構設計不合理、長事務、未提交事務等原因,頻繁出現 Locked 狀態進程堆積,導致正常業務請求阻塞、甚至資料庫不可用。臨時方案:編寫 Shell 腳本定時掃描並 Kill 這些進程,緩解癥狀,賏時間進行架構優化。
#!/bin/bash
# mysql_kill_locked.sh
# 定時清理 MySQL Locked 狀態進程
# 使用方式:加入 crontab,如每分鐘執行 */1 * * * * /path/mysql_kill_locked.sh
# ========== 配置區 ==========
MYSQL_PWD="your_root_password" # MySQL root 密碼
MYSQL_EXEC="/usr/local/mysql/bin/mysql" # mysql 客戶端路徑
TMP_DIR="/tmp"
FILE_SH="$TMP_DIR/mysql_kill_locked.sh" # 生成的 kill 腳本
FILE_TMP="$TMP_DIR/mysql_kill_locked.tmp" # 臨時進程列表
FILE_LOG="$TMP_DIR/mysql_kill_locked.log" # 執行日志
# ============================
# 1. 獲取所有 Locked 進程 ID
$MYSQL_EXEC -uroot -p$MYSQL_PWD -e "SHOW PROCESSLIST" | grep -i "Locked" > $FILE_TMP
# 2. 記錄日志
cat $FILE_TMP >> $FILE_LOG
# 3. 生成 kill 命令腳本
for line in $(cat $FILE_TMP | awk '{print $1}'); do
echo "$MYSQL_EXEC -uroot -p$MYSQL_PWD -e \"KILL $line\"" >> $FILE_SH
done
# 4. 執行 kill
chmod +x $FILE_SH
sh $FILE_SH
# 5. 清理臨時文件
> $FILE_SH
# 可選:保留日志最近 7 天
find $TMP_DIR -name "mysql_kill_locked.log" -mtime +7 -delete
KILL <id> 命令chmod +x /path/mysql_kill_locked.sh
/path/mysql_kill_locked.sh
cat /tmp/mysql_kill_locked.log # 查看是否有 Locked 進程被記錄
crontab -e
# 每 30 秒執行一次(需兩條配合)
* * * * * /path/mysql_kill_locked.sh
* * * * * sleep 30 && /path/mysql_kill_locked.sh
# 或每分鐘執行
*/1 * * * * /path/mysql_kill_locked.sh
#!/bin/bash
# 優化版:增加鎖等待時間閾值、白名單、告警
MYSQL_PWD="xxx"
MYSQL_EXEC="/usr/local/mysql/bin/mysql"
LOG_FILE="/var/log/mysql_kill_locked.log"
WHITELIST="12345 67890" # 不要 kill 的線程 ID(如備份線程)
THRESHOLD=30 # 超過 30 秒才 kill
# 獲取進程詳細信息
PROC_INFO=$($MYSQL_EXEC -uroot -p$MYSQL_PWD -e "SHOW FULL PROCESSLIST\G")
echo "$PROC_INFO" | awk -v thresh="$THRESHOLD" -v wl="$WHITELIST" '
BEGIN {
split(wl, white, " ")
for (i in white) whitelist[white[i]] = 1
}
/^Id:/ {id=$2}
/^Time:/ {time=$2}
/^State:/ {state=$0; sub(/^State: /, "", state)}
/^Info:/ {info=$0; sub(/^Info: /, "", info)}
/^$/ {
if (state ~ /Locked/ && time > thresh && !(id in whitelist)) {
print "KILL " id "; -- " info
}
}' | while read kill_cmd; do
echo "$(date) $kill_cmd" >> $LOG_FILE
$MYSQL_EXEC -uroot -p$MYSQL_PWD -e "$kill_cmd"
done
長期依賴 Kill 進程會導致:
必須同步進行:
SHOW ENGINE INNODB STATUS 分析鎖等待鏈Shell 定時 Kill Locked 進程是應對 MySQL 阻塞的應急手段。腳本核心是 SHOW PROCESSLIST | grep Locked | awk '{print $1}' | xargs -I {} mysql -e 'KILL {}'。生產環境請使用優化版(帶閾值、白名單、日志),並務必同步推進根治優化。