mysql权限需显式指定on database_name.*,否则无法use数据库;skip-show-databases配置或缺少库级权限会导致show databases不显示目标库;grant/revoke后无需flush privileges;revoke必须匹配grant的作用域。
grant 语句里漏写 on database_name.* 就没权限
很多人执行 grant select on *.* 或直接写 grant select,结果用户连 use database_name 都被拒绝——mysql 的权限是分层的,database_name.* 这部分不能省,它明确限定了作用域。不写,权限就落在全局(*.*)或表级(database_name.table_name),中间这个库级粒度一旦跳过,用户根本看不到该库的结构。
实操建议:
- 必须显式写出数据库名和通配符:
GRANT SELECT, INSERT ON myapp_db.* TO 'app_user'@'localhost' - 如果只给某张表权限,得写成
myapp_db.users,但这时用户仍无法USE myapp_db,除非额外加GRANT USAGE ON myapp_db.*(其实不够,见下条) -
USAGE权限本身不赋予任何操作能力,只允许连接;真正让USE生效的是至少一个库级权限(哪怕只是SELECT)
SHOW DATABASES 看不到目标库?检查 skip-show-databases 和用户权限范围
即使已执行 GRANT ... ON target_db.*,用户登录后执行 SHOW DATABASES 仍可能只看到 information_schema 和自己名字的库(如 mysql 不显示)。这不是权限没生效,而是两个原因叠加:MySQL 默认开启 skip-show-databases(配置项),或者用户没有对任何库的权限(包括 information_schema)。
实操建议:
- 确认 MySQL 配置文件中未启用
skip-show-databases;若启用了,该选项会强制隐藏所有库名,仅管理员可见 - 用户必须至少拥有一个库的显式权限(比如
GRANT SELECT ON target_db.*),否则SHOW DATABASES自动过滤掉无权限库 -
information_schema是特殊库,普通用户默认可查部分视图,但不会出现在SHOW DATABASES结果里——这是正常行为,不代表权限失败
权限生效要 FLUSH PRIVILEGES 吗?大多数情况不用
用 GRANT 或 REVOKE 修改权限后,权限立即生效,不需要手动 FLUSH PRIVILEGES。这条命令只在**直接修改 mysql.user、mysql.db 等系统表**后才需要——而那是危险操作,官方明确不推荐。
实操建议:
- 坚持用
GRANT/REVOKE,改完就生效,当前连接无需重连,新连接自然继承 - 如果发现权限没变,先检查是否输错用户名/主机名(
'user'@'192.168.%'和'user'@'%'是不同账户) - 执行
SHOW GRANTS FOR 'user'@'host'直接看当前生效权限,比猜更可靠
撤销权限时 REVOKE 不带 ON 子句会出事
REVOKE SELECT ON mydb.* FROM 'u'@'h' 是安全的;但写成 REVOKE SELECT FROM 'u'@'h'(漏掉 ON),MySQL 会尝试撤销全局 SELECT 权限——这不仅无效(因为用户本来就没全局权限),还可能触发警告甚至报错,尤其在 strict mode 下。
实操建议:
-
REVOKE必须严格匹配GRANT的作用域:之前授的是ON mydb.*,撤销时就得写全 - 想清空某个用户的全部权限?用
DROP USER 'u'@'h'更干脆,再重建(注意:MySQL 5.7+ 支持,且会自动清理权限) - 权限变更后,旧连接仍保持原有权限,直到断开重连——这点容易误判“撤销没生效”
最常被忽略的是权限作用域与连接主机名的精确匹配,'app'@'10.0.1.%' 和 'app'@'10.0.1.5' 是两个独立账户,授错一个就白忙活。还有就是误以为 GRANT 后必须 FLUSH,结果多敲一行反而暴露了对权限模型理解的偏差。











