SHOW DATABASES权限只能用ON .授予,其他写法如ON mydb.*均无效;必须确保host精确匹配、执行账户有GRANT权限、未启用skip-show-databases,且MySQL 8.0+角色需显式SET ROLE激活。

SHOW DATABASES权限只能用ON *.*授予,其他写法都无效
MySQL 的 SHOW DATABASES 权限是全局权限,语法上不支持库级或表级限定。你写 GRANT SHOW DATABASES ON mydb.* TO 'u'@'%' 不会报错,但权限根本不会写入系统表——查 SHOW GRANTS FOR 'u'@'%' 看不到它,登录后执行 SHOW DATABASES 仍报 ERROR 1227 (42501): Access denied。
真正有效的语句只有一种:
GRANT SHOW DATABASES ON *.* TO 'username'@'host';
这里的 *.* 是强制要求,不是占位符;host 必须和用户实际连接时的 host 完全一致(比如授权了 'dev'@'192.168.1.%',但连接用的是 'dev'@'localhost',权限不生效)。
授完权还看不到库?先检查这三件事
常见现象:命令执行成功,但用户登录后 SHOW DATABASES 仍为空或报错。这不是权限没给,而是环境链路断了:
-
GRANT语句执行账户本身没有GRANT OPTION,或不是SUPER/SYSTEM_USER角色——权限语句会静默失败 - 用户存在但主机名不一致:
SELECT User, Host FROM mysql.user WHERE User = 'username'确认注册的Host字段值 - MySQL 启用了
skip-show-databases配置项(在my.cnf中),此时任何GRANT都无效,必须改配置并重启
为什么给SELECT on mysql.db不行
有人试过 GRANT SELECT ON mysql.db TO 'u'@'%',以为能绕过限制,结果发现 SHOW DATABASES 依旧失败。这是因为:
-
SHOW DATABASES的行为由全局权限控制,和底层系统表访问权限完全解耦 -
mysql.db存的是「某个用户对某库的权限」,不是「所有库的列表」;它不参与SHOW DATABASES的输出逻辑 - 即使你能
SELECT * FROM mysql.db查出一堆库名,MySQL 也不会因此让SHOW DATABASES返回它们
MySQL 8.0+ 角色场景下容易漏掉SET ROLE ALL
如果用户绑定了角色(例如 CREATE ROLE db_reader; GRANT SHOW DATABASES ON *.* TO db_reader;),仅授角色还不够:
- 用户登录后默认不激活角色,
SHOW DATABASES仍失败 - 需显式执行
SET ROLE ALL;(或SET ROLE db_reader;)才能继承权限 - 若用程序连接,得在初始化 SQL 中加入该语句,否则每次连接都得手动激活
这个点在自动化部署或连接池场景里最容易被忽略——看起来权限都给了,但应用连上去就是看不到库名。











