MySQL不支持GRANT语句中用逗号分隔多个用户,须逐条授权或脚本批量生成;WITH GRANT OPTION仅允许转授自身显式拥有的权限,不支持越权或全局权限;跨主机授权需注意localhost与%账号独立匹配;REVOKE会级联清除下游转授权。
MySQL 的 GRANT 语句不支持在单条命令里用逗号写多个用户名,比如 GRANT SELECT ON db.* TO 'u1'@'%' , 'u2'@'%' 会直接报错 ERROR 1064 (42000)。必须逐条执行,或用脚本批量生成。
GRANT,例如:GRANT SELECT ON mydb.* TO 'alice'@'localhost'; GRANT SELECT ON mydb.* TO 'bob'@'192.168.1.%';
printf 生成多行 GRANT,再管道进 mysql -u root -p
GRANT 后权限不会自动刷新,但 MySQL 8.0+ 默认立即生效;5.7 及更早版本建议显式执行 FLUSH PRIVILEGES(不过只要没改 mysql.user 表底层,通常也不需要)授予 WITH GRANT OPTION,只允许被授权者把「自己已拥有的、且显式授予的」权限再转授他人,不能越权、不能授自己没拿到的权限,也不能授全局权限(如 CREATE USER)除非自己也有该权限。
GRANT SELECT, INSERT ON app.* TO 'dev'@'%' WITH GRANT OPTION; → dev 可以再给其他人授 SELECT 或 INSERT,但不能授 UPDATE,哪怕只对 app.*
WITH GRANT OPTION 对角色无效——必须直接授给用户账户GRANT OPTION 本身不可继承:A 授 B,B 授 C,C 无法再授 D,除非 B 显式加了 WITH GRANT OPTION
MySQL 认证时优先匹配最具体的 host,'user'@'localhost' 和 'user'@'%' 是两个完全独立的账号,可能同时存在。常见陷阱是:你给 'app'@'%' 授了权限,但应用连的是本地 socket(触发 localhost 匹配),结果提示 Access denied。
SELECT USER(), CURRENT_USER(); —— 前者是客户端声明的用户/主机,后者是服务器最终认证的账号localhost 版本:DROP USER 'app'@'localhost';,或确保两个账号权限一致'root'@'localhost',它和 'root'@'%' 无关,不能互相替代用 REVOKE 收回带 WITH GRANT OPTION 的权限时,MySQL 会自动删除所有由该用户转授出去的权限(即级联回收),这是默认行为,不可关闭。
A → GRANT ... TO B WITH GRANT OPTION; B → GRANT ... TO C;,然后 REVOKE ... ON ... FROM B; → C 的权限立刻失效,且 SHOW GRANTS FOR C 会显示为空SELECT * FROM mysql.tables_priv WHERE Grantor = 'B@%';(需有 SELECT 权限)查清 B 转授了哪些权限,避免误伤权限委托链越长,后期维护越容易失控;生产环境建议控制在 1 层以内,关键账号尽量由 DBA 直接管理。