剛建立的 MySQL 用戶明明密碼正確,卻總報 ERROR 1045 (28000): Access denied for user 'test'@'localhost'?這通常是因為 mysql.user 表中存在匿名用戶(user 為空字串),導致連線匹配優先級錯誤。本文詳細解析成因並提供解決方案。
# 建立用戶
mysql> GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' IDENTIFIED BY 'test' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
# 嘗試連線
$ mysql -u test -p
ERROR 1045 (28000): Access denied for user 'test'@'localhost' (using password: YES)
查看 mysql.user 表:
mysql> SELECT host, user FROM mysql.user;
+---------------------+------+
| host | user |
+---------------------+------+
| % | test |
| localhost | | <-- 匿名用戶
| localhost | root |
| test.saeg.com.cn | | <-- 匿名用戶
| test.saeg.com.cn | root |
+---------------------+------+
MySQL 連線驗證邏輯:按 host + user 排序,具體 host 優先於通配符 %,具體 user 優先於空 user。但當從 localhost 連線時,localhost 匿名用戶(user='')比 % 的 test 用戶優先級更高,導致認證走進匿名用戶通道,密碼當然不匹配。
DELETE FROM mysql.user WHERE user = '';
FLUSH PRIVILEGES;
UPDATE mysql.user SET user = 'test' WHERE user = '';
FLUSH PRIVILEGES;
新版本建議使用標準 DDL:
CREATE USER 'test'@'%' IDENTIFIED BY 'test';
GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION;
-- 或
CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';
/usr/local/mysql/my-*.cnf/usr/bin/mysql_install_db清理匿名用戶後,重新連線即可成功。生產環境部署時,執行 mysql_secure_installation 可自動移除匿名用戶、禁止 root 遠程登入、移除 test 資料庫,建議納入標準初始化流程。