MySQL 重裝或非正常關機導致授權表損壞、Root 密碼未知,連線報 ERROR 1045 (28000): Access denied for user 'root'@'localhost'。標準修復流程:停服務 → skip-grant-tables → 免密登入 → 重置密碼 → 恢復配置 → 重啟。本文提供完整命令序列與避坑細節。
systemctl stop mysqld
# 或 service mysqld stop
vim /etc/my.cnf
# 在 [mysqld] 區段下添加
skip-grant-tables
skip-networking # 建議同時關閉網路,防止無授權遠程訪問
systemctl start mysqld
mysql -u root
# 進入 MySQL 後
FLUSH PRIVILEGES; -- 5.7+ 必須先執行,否則 UPDATE 無效
-- MySQL 5.7
UPDATE mysql.user SET authentication_string=PASSWORD('NewP@ss123') WHERE User='root' AND Host='localhost';
-- MySQL 8.0 (authentication_string 已棄用,使用 authentication_string 或 ALTER USER)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewP@ss123';
FLUSH PRIVILEGES;
EXIT;
vim /etc/my.cnf # 刪除或註釋 skip-grant-tables, skip-networking
systemctl restart mysqld
mysql -u root -p'NewP@ss123' -e "SELECT VERSION();"
若 mysql.user 表結構異常或缺失,需初始化系統表:
# 停止服務
systemctl stop mysqld
# 備份舊數據目錄 (謹慎)
mv /var/lib/mysql /var/lib/mysql.bak.$(date +%F)
# 重新初始化 (MySQL 5.7)
mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
# MySQL 8.0
mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
# 啟動並按上述流程設定密碼
systemctl start mysqld
| 現象 | 原因 | 對策 |
|---|---|---|
| UPDATE 無效,密碼未變 | 未執行 FLUSH PRIVILEGES 或 5.7 欄位名錯誤 | 確認欄位 authentication_string,必須 FLUSH PRIVILEGES |
| 啟動報錯 skip-grant-tables 不生效 | 配置段落錯誤 (放在 [client] 或 [mysqld_safe]) | 確保在 [mysqld] 區段 |
| 遠程仍無法連線 | skip-networking 開啟、bind-address、防火牆、Host 欄位不匹配 | 檢查 SELECT User, Host FROM mysql.user; 授權對應 Host |
| 密碼策略拒絕 | validate_password 插件要求複雜度 | 暫時降低策略 SET GLOBAL validate_password.policy=LOW; 或用高強度密碼 |
全新安裝後直接執行:
mysql_secure_installation
# 互動式:設定 root 密碼、移除匿名用戶、禁止 root 遠程、移除 test 庫、重新載入授權表
核心提醒:
skip-grant-tables會讓 MySQL 完全失去存取控制,任何本地用戶均可無密操作資料庫。務必加上skip-networking限制本地,並在重置完成後 立即移除並重啟,切勿長期運行於此模式。