GRANT 语句怎么写才不会报错 Access denied 或 Illegal GRANT
MySQL 的
GRANT不是“给权限就完事”,它依赖两个前提:执行者本身有
GRANT OPTION权限,且目标用户(
'user'@'host')在
mysql.user表中已存在(或能被自动创建)。常见错误包括: 用普通账号执行
GRANT—— 报错
Access denied; you need (at least one of) the GRANT OPTION privilege(s)漏写主机名,比如只写
'myuser'而不是
'myuser'@'localhost'—— MySQL 会按
'myuser'@'%'匹配,可能授错对象 对不存在的数据库/表授予权限(如
GRANT SELECT ON nonexistent_db.* TO ...)—— 语句能执行,但后续访问仍报
Table doesn't exist,容易误判为权限问题
正确写法示例(以 root 登录后):
GRANT SELECT, INSERT ON `app_db`.* TO 'app_user'@'10.20.%' IDENTIFIED BY 'strong_pass_2024';
注意:
IDENTIFIED BY在 MySQL 8.0+ 中不推荐用于已有用户(应改用
ALTER USER),仅首次创建时可用;若用户已存在,去掉该子句。
REVOKE 删除权限后为什么 SHOW GRANTS 还显示旧权限
REVOKE执行成功不代表权限立即失效,因为 MySQL 权限缓存未刷新。用户当前连接仍保留旧权限,新连接才会生效。更关键的是:如果权限是通过不同 host 条目授予的(比如
'user'@'localhost'和
'user'@'127.0.0.1'),
REVOKE只影响显式指定的那一行,其余 host 条目不受影响。 执行
REVOKE SELECT ON app_db.* FROM 'app_user'@'10.20.%';后,立刻查
SHOW GRANTS FOR 'app_user'@'10.20.%';会更新,但
SHOW GRANTS FOR 'app_user'@'%';可能还有其它权限 必须手动运行
FLUSH PRIVILEGES;才能让所有连接感知变更(虽然多数情况下 MySQL 自动重载,但高并发或复制环境建议显式执行) 撤销所有权限的简写是
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host';,注意它不删除用户,只清空权限
MySQL 8.0 权限模型变化:ROLE 与 WITH GRANT OPTION 的区别
MySQL 8.0 引入角色(
CREATE ROLE),但角色权限和直接授权行为不等价。核心差异在于:
WITH GRANT OPTION允许被授权者再转授,而角色不能直接转授(需显式
GRANT ROLE ... TO ... WITH ADMIN OPTION)。 老写法:
GRANT SELECT ON sales.* TO 'analyst'@'%' WITH GRANT OPTION;→ analyst 可再执行
GRANT SELECT ON sales.* TO 'intern'@'%';角色写法:
CREATE ROLE 'sales_reader'; GRANT SELECT ON sales.* TO 'sales_reader'; GRANT 'sales_reader' TO 'analyst'@'%';→ analyst 默认无法把
sales_reader授给别人,除非加
WITH ADMIN OPTION权限继承是静态的:用户被授予角色后,角色权限变更会自动同步;但若用户已有直接权限,角色权限不会覆盖它
所以不要以为建了 role 就一劳永逸——
SHOW GRANTS会同时列出直接权限和角色权限,排查时得两头看。
最小权限原则落地:哪些权限其实不该轻易给
生产环境最常被过度授予、又最容易引发事故的权限有三个:
FILE、
PROCESS、
SUPER。它们不属于数据库对象操作,而是服务器级控制权。
FILE:允许用户读写服务器任意文件(
LOAD DATA INFILE/
SELECT ... INTO OUTFILE),一旦 Web 应用存在 SQL 注入,攻击者可直接读取
/etc/passwd或写入 Webshell
PROCESS:能看到所有连接的完整 SQL(含密码明文),
SHOW PROCESSLIST输出敏感信息
SUPER:可 kill 任意线程、修改全局变量(如关掉
sql_log_bin绕过 binlog)、甚至切换主从复制状态 —— 运维账号才应持有
真正业务账号,通常只需:
SELECT、
INSERT、
UPDATE、
DELETE(按需限制库/表),外加
EXECUTE(调用存储过程)和
SHOW VIEW(查视图)。连
CREATE都该由 DBA 统一管理。
