mysql中的SQL语句错误与执行权限分析

来源:这里教程网 时间:2026-02-28 20:45:16 作者:

MySQL报错“ERROR 1045: Access denied”时,先检查
mysql.user
表中的认证方式和主机匹配

这个错误表面是密码不对,实际常因用户账户的

Host
字段不匹配或认证插件不兼容导致。MySQL 8.0+ 默认用
caching_sha2_password
,而老客户端(如某些Python
mysql-connector
旧版本)只支持
mysql_native_password

查用户真实配置:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'your_user';
plugin
caching_sha2_password
且连接失败,可临时切回:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass';
Host
必须精确匹配——
'user'@'localhost'
'user'@'127.0.0.1'
,前者走 Unix socket,后者走 TCP,权限记录是分开的

执行
SELECT
报“ERROR 1142: SELECT command denied”,说明权限粒度没给到具体库表

MySQL权限分层级:全局(

*
)、库级(
db.*
)、表级(
db.table
)。即使给了
SELECT
权限,如果只授在
test.*
,却去查
production.users
,就会被拒。

确认当前用户有效权限:
SHOW GRANTS FOR 'user'@'host';
注意权限是否带
WITH GRANT OPTION
——没有它,用户无法转授权限
表级授权语法易错:
GRANT SELECT ON `mydb`.`users` TO 'u'@'%';
(反引号包裹库名/表名,避免关键字冲突)
改完权限后必须
FLUSH PRIVILEGES;
,否则不生效(仅对直接改
mysql
系统表的情况;用
GRANT
语句则自动刷新)

INSERT/UPDATE/DELETE
被拒绝,除了权限还可能卡在存储引擎或SQL模式

权限只是第一道关。即使有

INSERT
权限,也可能因表是
MyISAM
且磁盘满、或启用了严格模式(
STRICT_TRANS_TABLES
)导致空字符串插入
NOT NULL
字段失败。

查当前SQL模式:
SELECT @@sql_mode;
,若含
STRICT_TRANS_TABLES
INSERT INTO t(col) VALUES ('')
col VARCHAR(10) NOT NULL
会报错
检查存储引擎是否支持事务:
SHOW CREATE TABLE your_table;
,若为
MyISAM
START TRANSACTION
无效,且崩溃恢复能力弱
确认磁盘空间和
max_allowed_packet
——大BLOB插入失败时,错误码可能是
ERROR 2006
(MySQL server has gone away),而非权限问题

root
账号执行SQL仍报错,重点排查
DEFINER
和二进制日志设置

存储过程、视图、触发器里若声明了

DEFINER='someuser'@'host'
,即使你用
root
调用,MySQL也会按
DEFINER
的权限校验——此时
someuser
可能根本不存在或无权访问相关表。

查对象定义:
SHOW CREATE VIEW your_view;
,看
DEFINER
字段
临时解决:用
SET SQL_SECURITY_CONTEXT = 'CURRENT_USER';
(MySQL 8.0.30+)或重建对象时改
DEFINER=CURRENT_USER
开启
binlog
时,某些操作(如非确定性函数
UUID()
NOW()
)在
STATEMENT
格式下会被拒绝,报错类似
ERROR 1592
,需切
MIXED
ROW
格式
权限逻辑本身不复杂,但
Host
匹配、
DEFINER
上下文、SQL模式、存储引擎限制这四层容易叠在一起,单看错误码根本分不清哪一层断的。调试时别急着加
GRANT ALL
,先
SHOW GRANTS
SHOW CREATE
把执行路径里的每个环节都摊开看一遍。

相关推荐