生產環境因人員變動、手誤導致 MySQL root 密碼丟失是常見事故。MySQL 5.7+ 引入 auth_socket / caching_sha2_password 驗證插件,傳統 UPDATE user SET password=... 可能失效。本文提供兼容 5.6/5.7/8.0 的標準化重置流程,並解釋底層原理。
systemctl stop mysqld # 或 /etc/init.d/mysqld stop # 跳過授權表、跳過網絡啟動(極度不安全,僅限內網維護窗口) mysqld_safe --skip-grant-tables --skip-networking --user=mysql >/dev/null 2>&1 & # 等待 3-5 秒確保啟動完成 sleep 5
mysql -uroot
MySQL 5.6 / 5.7 (mysql_native_password):
USE mysql;
UPDATE user SET authentication_string=PASSWORD('NewStrongPass#2024') WHERE User='root' AND Host='localhost';
FLUSH PRIVILEGES;
MySQL 5.7 (auth_socket) / 8.0 (caching_sha2_password):
USE mysql;
-- 5.7 修改 plugin 為 mysql_native_password
UPDATE user SET plugin='mysql_native_password', authentication_string=PASSWORD('NewStrongPass#2024') WHERE User='root' AND Host='localhost';
-- 8.0 直接用 ALTER USER(需先 flush privileges 刷新 grant 表)
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPass#2024';
# 關閉跳過權限的實例 mysqladmin -uroot -p'NewStrongPass#2024' shutdown # 正常啟動 systemctl start mysqld # 驗證 mysql -uroot -p'NewStrongPass#2024' -e "SELECT VERSION(), CURRENT_USER();"
#!/bin/bash
# reset_mysql_root.sh -- 需 root 執行
set -euo pipefail
NEW_PASS="${1:-$(openssl rand -base64 16)}"
SOCKET="${2:-/var/lib/mysql/mysql.sock}"
systemctl stop mysqld 2>/dev/null || service mysqld stop 2>/dev/null
mysqld_safe --skip-grant-tables --skip-networking --socket="$SOCKET" --user=mysql >/dev/null 2>&1 &
sleep 5
mysql --socket="$SOCKET" -uroot -e "
USE mysql;
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '$NEW_PASS';
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '$NEW_PASS';
ALTER USER 'root'@'::1' IDENTIFIED BY '$NEW_PASS';
" 2>/dev/null || {
# 兼容 5.6/5.7 旧语法
mysql --socket="$SOCKET" -uroot -e "
USE mysql;
UPDATE user SET authentication_string=PASSWORD('$NEW_PASS'), plugin='mysql_native_password' WHERE User='root';
FLUSH PRIVILEGES;
"
}
mysqladmin --socket="$SOCKET" -uroot -p"$NEW_PASS" shutdown
systemctl start mysqld
echo "Root password reset to: $NEW_PASS"
echo "Please save it securely!"
--skip-grant-tables:跳過 mysql.user 權限檢查,任何用戶可無密登入並擁有所有權限。--skip-networking:禁用 TCP/IP,僅允許本地 Socket 連接,防止外部入侵維護窗口。authentication_string 欄位存儲加密密文,5.7+ PASSWORD() 棄用,8.0 僅支援 ALTER USER。FLUSH PRIVILEGES:將 grant 表修改同步到內存權限結構,否則新密碼不生效。DROP USER ''@'localhost';UPDATE user SET Host='localhost' WHERE User='root'; FLUSH PRIVILEGES;VALIDATE_PASSWORD 插件,強制長度、混合字符、過期輪換。max_connect_errors、skip-name-resolve 減少暴力破解面。忘記 root 密碼不可怕,可怕的是無標準化流程導致維護窗口過長、或重置後安全配置缺失。收藏此腳本,關鍵時刻 3 分鐘搞定,事後按清單加固,才是專業 DBA 的態度。