error 1142并非当前用户缺权限,而是mysql按视图或存储过程的definer账号校验基表权限:若definer不存在、无基表select权或未执行flush privileges,即使当前用户已授权仍失败;同时需确认current_user()身份匹配、默认库已指定、host解析正确及bind-address配置合规。

SELECT报ERROR 1142但SHOW GRANTS显示有权限
这不是当前用户缺权限,而是MySQL根本没检查你——它在查视图或存储过程的DEFINER账号。执行SELECT USER(), CURRENT_USER();,如果返回'app'@'10.0.1.5'和'app'@'%',那真正参与校验的是后者;但如果你只给'app'@'10.0.1.5'授过权,就完全不生效。
快速定位步骤:
- 用
SHOW CREATE VIEW your_view\G确认DEFINER和SQL SECURITY(默认是DEFINER) - 查DEFINER是否存在:
SELECT User, Host FROM mysql.user WHERE User = 'definer_user' AND Host = 'host'; - 查DEFINER真实权限:
SHOW GRANTS FOR 'definer_user'@'host';
GRANT后SELECT仍失败,是否漏了FLUSH PRIVILEGES
MySQL把权限缓存在内存里,尤其在容器、旧版本或高并发写入场景下,GRANT执行完不刷新,新权限可能延迟甚至不生效。
必须跟一句:
FLUSH PRIVILEGES;- 再验证:
SHOW GRANTS FOR CURRENT_USER();,确保输出里真有SELECT ON db.table或SELECT ON db.*
别依赖“执行成功就完事”——这步跳过,90%的“授权无效”问题都卡在这儿。
表存在但SELECT提示“Table doesn't exist”
不是权限问题,是上下文错位:没指定默认库,或连接时host解析出偏差。
先确认当前库:SELECT DATABASE();,如果返回NULL,说明没选库,所有未限定名的表都会被当作当前库下对象解析——而你可能在sales库建表,却连着mysql库执行SELECT * FROM orders;。
解决方式:
- 连接时加
-D sales参数 - 登录后立即执行
USE sales; - 写全限定名:
SELECT * FROM sales.orders; - 注意
localhost走Unix socket,127.0.0.1走TCP,权限记录是分开的,'user'@'localhost'≠'user'@'127.0.0.1'
云环境或Docker里查不到表,bind-address还在127.0.0.1
即使'user'@'%'权限写得再全,只要MySQL配置里bind-address = 127.0.0.1,外部TCP包根本进不来——所谓“远程连上了”,其实是连到了本地socket或误用了跳板机。
必须检查并修正:
- 配置文件(如
/etc/mysql/mysql.conf.d/mysqld.cnf)中[mysqld]段的bind-address,注释掉或改为0.0.0.0 - 重启服务:
sudo systemctl restart mysql - 验证监听:
ss -tln | grep :3306,输出里应含*:3306或0.0.0.0:3306,而非仅127.0.0.1:3306 - 云服务器额外检查安全组是否放行3306入方向
最容易被忽略的是:改完配置不重启,或者只开了系统防火墙(如ufw),却忘了云平台的安全组——这两层都得通。











