最可靠方式是执行 SHOW GRANTS FOR 'user'@'host' 并人工筛选目标库表权限;因普通账号无 mysql.tables_priv 读取权限,且 SHOW GRANTS 必须用完整 User@Host、区分大小写与反引号,DNS 不匹配时亦不生效。

直接执行 SHOW GRANTS FOR 'user'@'host',然后人工筛选含目标库表的语句——这是最可靠、权限要求最低的方式。
为什么不用直接查 mysql.tables_priv?
普通账号几乎肯定没权限读 mysql 库:SELECT * FROM mysql.tables_priv 会报错 ERROR 1142 (42000): SELECT command denied to user。这不是配置疏漏,是 MySQL 的安全默认:应用账号不该有系统表读取权。硬要开这个权限,反而引入风险,得不偿失。
SHOW GRANTS FOR 'user'@'host' 必须带完整主机名
常见错误是只写用户名,比如 SHOW GRANTS FOR 'app_user';,结果报错 ERROR 1141 (42000): There is no such grant defined for user 'app_user' on host '%'。MySQL 把 'app_user'@'localhost' 和 'app_user'@'%' 当作两个独立账户。
- 先确认真实注册信息:
SELECT User, Host FROM mysql.user WHERE User = 'app_user'; - 复制输出中的完整
User@Host字符串(注意单引号和大小写),粘贴进SHOW GRANTS FOR命令 - 特别注意:DNS 解析失败时,
'app_user'@'192.168.1.%'不匹配'app_user'@'192.168.1.100'
想快速定位某张表的权限?用文本筛选更高效
SHOW GRANTS 输出是可执行的 SQL 语句,格式清晰。查 syslog.audit_log 表权限时,重点找包含 ON `syslog`.`audit_log` 的行(反引号、库名、表名三者必须完全一致,大小写敏感)。
- 在命令行里可以用
grep:mysql -e "SHOW GRANTS FOR 'u1'@'%'" | grep "syslog\.audit_log" - 别依赖
ON dbname.tablename语法——SHOW GRANTS FOR 'u1'@'%' ON syslog.audit_log是无效命令,MySQL 不支持这种限定查询 - 如果用户绑了角色(MySQL 8.0+),
SHOW GRANTS不展开角色继承的权限,需额外查mysql.role_edges关联角色再查角色权限
查到权限后发现不生效?先看 FLUSH PRIVILEGES
无论是用 GRANT 还是手动改 mysql.tables_priv,MySQL 都不会自动重载权限缓存。旧连接仍用旧规则,新连接才读新配置。
- 执行完授权操作后,必须立刻运行:
FLUSH PRIVILEGES; - 脚本批量操作时最容易漏掉这句,调试前先检查它是否被执行
-
FLUSH PRIVILEGES不影响当前连接的权限判断逻辑,只刷新服务端缓存,对已建立连接无即时效果
真正容易被忽略的是 CURRENT_USER() 和 USER() 的区别——SHOW GRANTS 查的是前者,而你登录时填的可能是后者。权限校验只认 CURRENT_USER() 对应的那条记录,不是你“以为自己是谁”。


















