mysql禁止用revoke撤回用户对mysql系统库的访问权,因其将该库只读访问视为管理功能;需通过剥夺全局select权限或drop user来实现阻断,且验证须新开连接。

直接执行 REVOKE 无法撤掉对 mysql 库的访问权
MySQL 不允许你用 REVOKE 撤回用户对 mysql 系统库的 SELECT 或其他操作权限——这不是疏漏,是硬性限制。哪怕你当初是用 GRANT SELECT ON mysql.* TO 'user'@'%' 显式授的权,REVOKE SELECT ON mysql.* FROM 'user'@'%' 也会静默失败(返回 Query OK,但权限仍在)。根本原因是:MySQL 内部把对 mysql 库的只读访问视为管理功能的一部分,不走常规权限校验路径。
SHOW GRANTS FOR 看不到 mysql 库权限,但实际可能有
执行 SHOW GRANTS FOR 'user'@'%' 通常不会显示任何关于 mysql 库的条目,但这不代表用户没权限。只要该用户拥有 SELECT 权限(哪怕只是 SELECT ON *.*),MySQL 就默认允许其查 mysql.db、mysql.user 等只读视图(注意:不能改,只能查)。这是为了兼容运维习惯,比如 DBA 查账号列表、应用监控连上后验证自身权限等。
- 真正能禁用这种隐式访问的,只有两类操作:剥夺全局
SELECT权限,或彻底移除用户 - 如果用户只有
SELECT ON app_db.*,那他根本查不了mysql库——此时无需额外操作 - 若用户有
SELECT ON *.*,则必须先REVOKE SELECT ON *.* FROM 'user'@'%',再按需重授业务库权限
想彻底阻断访问?只能靠 DROP USER 或重置权限粒度
没有“仅关 mysql 库”的开关。可行路径只有两个:
- 用
DROP USER 'user'@'%'彻底删除账号(适合测试/临时账号) - 重做权限体系:先
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'%',再只授业务所需库表,例如GRANT SELECT, INSERT ON order_db.* TO 'user'@'%' - 切勿尝试手动更新
mysql.db表——修改后必须FLUSH PRIVILEGES,且后续任意GRANT/REVOKE都可能覆盖你的改动,状态不可控
验证是否真生效,得换连接、别信旧会话
执行完 REVOKE 后,立刻用原连接执行 SELECT COUNT(*) FROM mysql.user,很可能仍成功——因为旧连接缓存了权限。必须新开一个连接(如 mysql -u user -p -h host)再试,报错 ERROR 1142 (42000): SELECT command denied to user 才算到位。
最容易被忽略的是:很多应用用连接池,即使你改了权限,池子里的旧连接还能继续查 mysql 库数小时。要真正落地,得重启服务或等连接超时淘汰。











