MySQL 5.7 初始化会生成匿名用户(User = ''),需用DROP USER逐条删除并FLUSH PRIVILEGES,再通过SELECT和实连验证清零;若root密码为空,须用ALTER USER加固。

MySQL 5.7 中的匿名用户(User = '')不是配置错误,而是初始化时写死的行为;不手动删除,它就一直存在,并且可能抢在 root@localhost 前匹配登录请求——你以为登的是 root,实际是权限为零的空用户。
先确认有没有,别删错也别漏删
空用户名 ≠ NULL,也不等于 'anonymous' 或 ' '(带空格)。唯一可靠判断方式是:
SELECT User, Host FROM mysql.user WHERE User = '';
常见结果包括:''@'localhost'、''@'127.0.0.1'、''@'::1'。如果启用了 skip-name-resolve,这三者互不等价,都得单独处理。返回空结果?那直接跳过后续所有删除操作。
MySQL 5.7 必须用 DROP USER,DELETE 会失败
MySQL 5.7+ 不支持对空用户名执行 DELETE FROM mysql.user 后再 FLUSH PRIVILEGES 的老办法——它会报错 ERROR 1396 (HY000): Operation DROP USER failed,但更关键的是:你根本不能用 DELETE 安全删掉它,因为权限系统会拒绝该操作或留下残留状态。
正确做法是逐条执行:
DROP USER ''@'localhost';<br>DROP USER ''@'127.0.0.1';<br>DROP USER ''@'::1';<br>FLUSH PRIVILEGES;
-
DROP USER会同时清理用户记录和其关联的所有权限,比手删表干净 - 必须显式列出每个
Host,不能只删localhost就以为完事 - 删完不执行
FLUSH PRIVILEGES,缓存未更新,mysql -u '' -h localhost仍可能连得进去
删完立刻验证,重点看 CURRENT_USER()
很多人删完就以为安全了,但没验证就等于没做。两步缺一不可:
① 查表确认清零:
SELECT User, Host FROM mysql.user WHERE User = '';
必须返回空集。
② 实连验证身份:
mysql -u root -p -e "SELECT USER(), CURRENT_USER();"
如果 CURRENT_USER() 返回 @localhost 或 @127.0.0.1,说明仍有匿名用户生效,或者 root@localhost 被覆盖/缺失——此时你看到的 USER() 是你声明的用户名,而 CURRENT_USER() 才是 MySQL 实际匹配到的账号。
别让 root 成为“替罪羊”
很多所谓“匿名登录成功”,真实原因是 root@localhost 密码为空。执行以下检查:
SELECT User, Host, authentication_string FROM mysql.user WHERE User = 'root';
若 authentication_string 字段为 '' 或 *(MySQL 5.7),说明 root 没设密码。这时候即使删光所有匿名用户,mysql -u root 依然能直连——风险一点没少,只是伪装成了“匿名问题”。
真正要做的,是在删完匿名用户后,立刻加固 root@localhost:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongPass123!';
注意:不要用 SET PASSWORD 或直接 UPDATE mysql.user,5.7+ 推荐用 ALTER USER,它会自动处理密码哈希与插件兼容性。


















