grant all privileges on . 仅授予所有数据库/表的dml、ddl等常规对象权限,不包含create user、reload、shutdown、grant option及process等管理与系统权限,需显式单独授权。

GRANT ALL PRIVILEGES ON *.* 会赋予哪些实际权限
MySQL 的 GLOBAL 权限层级(即 ON *.*)不是“所有功能全开”,而是指对**所有数据库、所有表、所有未来新建库表**生效的权限集合。它不包含 CREATE USER、RELOAD、SHUTDOWN 这类管理型权限,也不自动包含 GRANT OPTION——后者必须显式声明。
常见误判是以为 GRANT ALL ON *.* 就等于 root,其实它缺了关键管理能力;真正接近 root 的写法是:GRANT ALL PRIVILEGES ON *.* TO 'u'@'h' WITH GRANT OPTION。
-
ALL PRIVILEGES在*.*上覆盖的是 DML(SELECT/INSERT/UPDATE/DELETE)、DDL(CREATE/DROP/ALTER)、索引、视图、存储过程等常规对象权限 - 但
PROCESS、REPLICATION CLIENT、SUPER等动态系统权限需单独授予,例如:GRANT PROCESS ON *.* TO 'u'@'h' - MySQL 8.0+ 中,
APPLICATION_PASSWORD_ADMIN、BACKUP_ADMIN等新权限也完全独立于ALL PRIVILEGES,不会被隐式包含
为什么用 CREATE USER + GRANT 分两步更安全
直接 GRANT ... TO 'u'@'h' 在用户不存在时会自动创建,但密码策略、账户锁定、过期时间等关键安全属性全按默认值来——比如 MySQL 8.0 默认用 caching_sha2_password,而旧客户端可能连不上;又比如账户没设 PASSWORD EXPIRE,长期不换密就埋雷。
分两步能精确控制初始状态:
- 先用
CREATE USER 'u'@'h' IDENTIFIED WITH caching_sha2_password BY 'pwd' PASSWORD EXPIRE INTERVAL 90 DAY FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 1定义强约束 - 再用
GRANT SELECT, INSERT ON *.* TO 'u'@'h'赋权,避免权限和身份配置耦合 - 如果跳过
CREATE USER直接GRANT,MySQL 5.7 会用空密码创建用户(极危险),8.0 虽改用随机密码但不可控,运维排查成本陡增
GLOBAL 权限在 MySQL 8.0 的角色继承限制
MySQL 8.0 引入角色(ROLE)后,GLOBAL 权限不能通过角色间接授予。也就是说:CREATE ROLE r; GRANT SELECT ON *.* TO r; 是合法的,但 GRANT r TO 'u'@'h' 不会让用户获得全局 SELECT 权限——这条语句执行成功,但权限实际不生效。
这是容易踩坑的关键点:角色只能承载数据库级(db.*)或表级权限,*.* 必须直授给用户或代理用户(PROXY)。
- 验证方式:登录用户后执行
SHOW GRANTS;,若结果里没有ON *.*字样,说明角色没带过去 - 替代方案:用
SET DEFAULT ROLE r TO 'u'@'h'配合直授的GRANT ... ON *.*,角色只管局部权限 - 跨版本注意:MySQL 5.7 根本不支持角色,所以该限制只存在于 8.0+,升级后务必重检权限脚本
撤销 GLOBAL 权限时为什么有时不生效
最常见原因是 REVOKE 语句没匹配到原始授权粒度。MySQL 权限检查是“最小匹配原则”:如果用户通过多个来源获得同一权限(比如 GRANT SELECT ON *.* 和 GRANT SELECT ON db1.*),只撤销其中一个,SELECT 仍有效。
更隐蔽的问题是代理权限(PROXY)干扰:若用户 A 被设为用户 B 的 proxy(GRANT PROXY ON 'b'@'%' TO 'a'@'%'),而 B 拥有 *.* 权限,那么 A 登录后实际继承 B 的全局权限,此时对 A 执行 REVOKE 完全无效。
- 查清真实权限来源:执行
SELECT * FROM mysql.role_edges;和SELECT * FROM mysql.proxies_priv; - 彻底清理:先
REVOKE PROXY ON 'b'@'%' FROM 'a'@'%',再对 B 撤权,最后才对 A 撤权 - 权限缓存:修改后必须执行
FLUSH PRIVILEGES;,否则内存中旧权限继续生效(尤其在非管理员账号下操作时容易忽略)
GLOBAL 权限的粒度粗、影响广,一旦误授很难追溯具体哪条 SQL 触发了越权行为;生产环境应尽量用数据库级(db.*)或表级权限兜底,只在监控、备份等明确需要跨库操作的场景才启用 *.*,且必须配 WITH GRANT OPTION 的审计日志和定期权限巡检。











