SHOW DATABASES权限控制用户能否列出服务器上所有数据库名称,而非控制对库内数据的访问;该权限只能在全局(.)授予,授予后用户执行SHOW DATABASES可看到全部库名,即使对其中某些库无任何操作权限。

SHOW DATABASES 权限到底控制什么
它不是“能看到哪些库”,而是“能否列出所有数据库名”。即使用户对某个库完全没有 SELECT 权限,只要拥有 SHOW DATABASES,就能在 SHOW DATABASES 输出里看到那个库的名字。反过来,没这个权限时,SHOW DATABASES 只返回空结果或报错 ERROR 1227 (42501): Access denied; you need (at least one of) the SHOW DATABASES privilege(s) for this operation。
授予全局 SHOW DATABASES 权限(最常用)
这是开发人员连上 MySQL 后能直接执行 SHOW DATABASES 的最低要求:
GRANT SHOW DATABASES ON *.* TO 'devuser'@'%';- 必须搭配
FLUSH PRIVILEGES;才生效 - 注意:这里用的是
*.*,不是mysql.*或devdb.*——SHOW DATABASES是服务器级权限,只能在全局范围(*.*)授予 - 如果用户已存在但没权限,直接
GRANT即可;如果是新建用户,建议在CREATE USER后再GRANT,避免隐式创建带来的主机名匹配问题
为什么不能用 dbname.* 授予 SHOW DATABASES
你可能会看到类似 GRANT SHOW DATABASES ON myapp.* TO 'devuser'@'%' 的写法,但它实际无效:
- MySQL 不支持在库级作用域(
myapp.*)授予SHOW DATABASES—— 语法虽不报错,但权限不会写入mysql.global_priv表(MySQL 8.0+)或mysql.user表(5.7),SHOW GRANTS FOR 'devuser'@'%'里也看不到这条记录 - 试图用
dbname.*授权后执行SHOW DATABASES,依然会提示权限不足 - 唯一合法的作用域是
*.*;若只想限制用户“只看得到部分库”,得靠其他机制(如启用skip-show-databases配置 + 账户隔离),而非权限控制
开发人员连上就看不到库?先检查这几个点
授完权还报错,常见卡点如下:
- 执行
GRANT的账户本身没GRANT OPTION,或不是root/ 具备SYSTEM_USER角色的高权限用户 - 忘了
FLUSH PRIVILEGES;,尤其在 MySQL 5.7 及更早版本中,权限缓存不会自动刷新 - 用户连接时用的是
'devuser'@'localhost',但授权语句写的是'devuser'@'%'—— 主机名必须完全匹配,localhost和127.0.0.1在 MySQL 中被视为不同主机 - MySQL 8.0+ 启用了
activate_all_roles_on_login=ON且用户有角色,但角色没被激活,导致权限未继承;可用SET ROLE ALL;临时验证
真正麻烦的不是授权动作本身,而是主机名匹配和权限刷新这两个环节——它们不报明显错误,却让授权看起来“没生效”。


















