SHOW GRANTS 返回空或仅USAGE,通常因用户@主机组合不匹配;MySQL权限按'user'@'host'精确匹配,localhost与127.0.0.1视为不同账号,需用完整形式如'SHOW GRANTS FOR 'u1'@'localhost''查询。

查权限时为什么 SHOW GRANTS 返回空或只有 USAGE?
这通常不是没权限,而是你查的是错误的用户+主机组合。MySQL 的权限是按 'user'@'host' 精确匹配的,脚本里连的是 localhost,但 SHOW GRANTS FOR 'u1' 默认查的是 'u1'@'%',两者不等价。
实操建议:
- 先确认脚本实际连接参数:看连接字符串里的
host值,常见有127.0.0.1、localhost、db.example.com - 用完整形式查权限:
SHOW GRANTS FOR 'u1'@'localhost'(把localhost换成真实 host) -
localhost在 MySQL 里会走 socket 连接,和127.0.0.1(TCP)是两个不同账号,别混用
脚本报错 ERROR 1142 (42000): SELECT command denied 怎么快速定位缺哪条权限?
别猜,直接从 SQL 语句反推。MySQL 的权限检查粒度很细,比如 SELECT 权限分库级、表级、列级,而 INSERT 还可能卡在 AUTO_INCREMENT 列或触发器上。
实操建议:
- 把脚本里报错那条 SQL 单独拿出来,在有权限的账号下执行
EXPLAIN FORMAT=TREE(8.0+)或EXPLAIN,看是否涉及子查询、临时表、视图——这些都可能额外要求SELECT或CREATE TEMPORARY TABLES - 检查是否用了函数:如
NOW()没问题,但SYS.DBMS_LOCK.SLEEP()就需要EXECUTE权限 - 用
SELECT * FROM information_schema.TABLE_PRIVILEGES WHERE GRANTEE LIKE '%u1%'查具体表级授权,比SHOW GRANTS更细
用 mysql_upgrade 或备份恢复脚本失败,真是权限不够吗?
不一定。很多运维脚本失败表面是权限问题,其实是 MySQL 版本升级后系统库结构变化,老账号没被自动授予新权限(比如 5.7→8.0 后,performance_schema 表默认需要显式授权)。
实操建议:
- 先看错误日志里具体访问了哪个库/表,比如报
mysql.proc拒绝,说明需要SELECT权限;报sys.schema_table_statistics,就得给sys库授权 - 8.0+ 中,
root默认也不再有mysql.*全权限,要用GRANT SYSTEM_VARIABLES_ADMIN ON *.*这类新权限项 - 避免直接授
ALL PRIVILEGES,改用最小集:比如备份脚本只需SELECT, LOCK TABLES, RELOAD, SHOW VIEW
写权限排查脚本时,为什么 information_schema 查询结果和 SHOW GRANTS 对不上?
因为 information_schema 显示的是当前生效权限快照,而 SHOW GRANTS 读的是 mysql.user 表原始记录——中间可能有 FLUSH PRIVILEGES 没执行,或权限刚改但连接未重连。
实操建议:
- 排查脚本里别只查
information_schema,加一句SELECT USER(), CURRENT_USER()确认实际生效账号 - 如果发现权限已授但不生效,优先
FLUSH PRIVILEGES,再检查客户端是否复用旧连接(尤其 Python 的pymysql默认长连接) -
information_schema.ROLE_TABLE_PRIVILEGES在启用了角色的实例中才有效,没开activate_all_roles_on_login的话,角色权限不会自动合并到当前会话
权限不是静态配置,它依赖连接时的 host 解析、角色激活状态、甚至 SQL 模式(比如 sql_mode=NO_ENGINE_SUBSTITUTION 会影响表创建权限判断)。最稳妥的方式,永远是用脚本实际使用的账号和 host 组合,手动复现那条失败 SQL。


















