root用户能登录但show databases报空,说明mysql.user表中root对应的所有*_priv字段(如select_priv、grant_priv等)均为'n',需通过--skip-grant-tables跳过权限验证后,精准更新指定host(如localhost)的全部权限字段为'y',并确保super_priv='y'及认证插件兼容,最后执行flush privileges生效。

root用户能登录但SHOW DATABASES报空,说明权限字段全为'N'
这不是密码或连接问题,而是mysql.user表里root对应的所有*_priv字段(比如Select_priv、Create_priv)被设成了'N'。即使你还能进MySQL,USE mysql、SHOW TABLES这类操作也会被拒绝。
直接执行GRANT ALL ON *.* TO 'root'@'localhost'会失败——因为当前账户没有Grant_priv,连授权权限都没有。
- 先确认现状:
SELECT User, Host, Select_priv, Grant_priv, Super_priv FROM mysql.user WHERE User = 'root'; - 如果看到多个
'N',别犹豫,立刻切到跳过权限模式 - 注意:MySQL 8.0+ 的密码字段是
authentication_string,不是password;5.7及以前才是password
用--skip-grant-tables启动后,UPDATE语句必须带WHERE条件限定Host
跳过权限验证后,mysql -u root能直连,但UPDATE mysql.user SET ...若不指定Host,可能批量改错行——比如root@'%'和root@'localhost'权限不同,混在一起更新会导致远程访问失效或本地无法登录。
常见错误是只写WHERE User='root',结果把所有host的root都改了,而生产环境往往只允许root@'127.0.0.1'或root@'localhost',其他host本就不该有root。
- 查清目标host:
SELECT User, Host FROM mysql.user WHERE User = 'root'; - 针对性更新(以
localhost为例):UPDATE mysql.user SET Select_priv='Y', Insert_priv='Y', Update_priv='Y', Delete_priv='Y', Create_priv='Y', Drop_priv='Y', Reload_priv='Y', Shutdown_priv='Y', Process_priv='Y', File_priv='Y', Grant_priv='Y', References_priv='Y', Index_priv='Y', Alter_priv='Y', Show_db_priv='Y', Super_priv='Y', Create_tmp_table_priv='Y', Lock_tables_priv='Y', Execute_priv='Y', Repl_slave_priv='Y', Repl_client_priv='Y', Create_view_priv='Y', Show_view_priv='Y', Create_routine_priv='Y', Alter_routine_priv='Y', Create_user_priv='Y', Event_priv='Y', Trigger_priv='Y', Create_tablespace_priv='Y' WHERE User='root' AND Host='localhost'; - MySQL 8.0+ 必须再执行
FLUSH PRIVILEGES;才生效;5.7之前部分版本可省略,但加上更稳妥
重启后GRANT ALL仍失败?检查是否遗漏Super_priv或认证插件冲突
重启MySQL后,用新密码登录,执行GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION;报错ERROR 1045,大概率是Super_priv没开,或者MySQL 8.0+用了caching_sha2_password插件但客户端不兼容。
Super_priv是执行GRANT的前提——它控制是否能修改全局系统变量、重启服务等,缺了就无法授全局权限。而插件不匹配会导致看似登录成功,实际权限校验绕过失败。
- 验证
Super_priv:SELECT Super_priv FROM mysql.user WHERE User='root' AND Host='localhost';,必须是'Y' - MySQL 8.0+ 若用旧客户端(如Navicat老版本),需重置认证方式:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 别漏掉
WITH GRANT OPTION——没这个,root自己能用,但不能给别人授权
备份缺失时,手动插入root用户的风险点
如果SELECT ... FROM mysql.user WHERE User='root'返回空,说明root记录被删了,此时得INSERT INTO mysql.user。这比更新字段危险得多:字段顺序、默认值、加密方式稍错,就会导致无法登录或权限不生效。
最易踩的坑是忽略MySQL版本差异:plugin字段在5.7是'mysql_native_password',8.0默认是'caching_sha2_password';authentication_string在8.0必须用PASSWORD()函数生成(5.7)或SHA2()哈希(8.0),直接填明文会锁死账户。
- 安全做法:从同版本正常实例导出一行
root记录,改Host和authentication_string后导入 - 应急插入务必查文档确认字段列表,尤其
account_locked(8.0+)、password_expired等新增字段 - 插入后必须
FLUSH PRIVILEGES;,且不能用mysqld --skip-grant-tables以外的方式启动——否则插入的数据不加载
修复过程里最容易被忽略的,是Host粒度控制和Super_priv的必要性。很多人修完权限字段就以为万事大吉,结果发现GRANT还是报错,回头查才发现Super_priv='N'卡住了最后一步。











