权限报错的排查路径
遇到权限类报错,先确认「当前账号 + 来源主机 + 目标对象」这三元组,再用 SHOW GRANTS 对照缺失项。MySQL 授权的最小单位是账号与来源主机的组合,同名账号在不同来源主机下是两条独立记录,这也是「本地能用、远程不能用」的常见原因。
高频权限报错
| 错误码 | 含义 | 典型场景 |
|---|---|---|
| 1142 | SELECT command denied to user | 授权范围不含该表或库 |
| 1044 | Access denied for user to database | 库级权限缺失,连接默认库就被拒 |
| 1045 | Access denied for user | 密码错误、来源主机不匹配或账号被锁定 |
| 1227 | 需要 SUPER 等动态权限 | 改全局参数、设置 GTID、导入含 DEFINER 的对象 |
| 1370 | execute command denied to user | 存储过程的 EXECUTE 权限未授予 |
| 1419 / 1449 | DEFINER 相关错误 | 导入的视图或函数定义了不存在的执行者 |
排查步骤
排查步骤
SELECT CURRENT_USER(), USER(), CURRENT_ROLE(); # 区分实际认证身份与登录身份
SHOW GRANTS FOR CURRENT_USER(); # 当前账号的授权清单
SHOW GRANTS FOR 'app'@'10.0.%'; # 指定账号的授权
SELECT * FROM information_schema.user_privileges WHERE grantee LIKE "'app'%"; # 全局权限
SHOW WARNINGS; # 部分权限问题会带出线索
-- 授权示例:按最小权限补足
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'10.0.%';典型使用场景
- 新环境部署后应用连接报 1045,核对来源主机与密码
- 导入他人备份报 1227,确认是否涉及 DEFINER 与全局参数
- 只读账号误报 1142,检查授权范围是否覆盖目标表
- 用角色管理权限时确认角色是否已激活
- 排查代理或中间件场景下身份与预期不一致
判断权限要用 CURRENT_USER():USER() 是客户端声明的登录名,经代理或角色切换后两者可能不一致,用错函数会得出相反结论。
8.0 的动态权限体系把 SUPER 拆分细化,老文档里的 GRANT SUPER 可能仍不够,需按报错提示授予具体的动态权限。
排查顺序建议
- 先确认实际认证身份,再列出该身份的全部授权记录
- 核对来源主机是否与授权记录完全匹配,含通配写法
- 确认目标对象所在的库表是否落在授权范围内
- 检查是否缺少动态权限,或角色未激活导致权限不生效
- 补授权后重新连接验证,避免老会话仍持有旧权限