全局权限能跨库操作,数据库级权限只能作用于指定库
MySQL 的权限体系是分层的,
GRANT语句中指定的权限作用域直接决定用户能做什么。全局权限(如
GRANT SELECT ON *.*)表示对所有现有和未来创建的数据库都生效;而数据库级权限(如
GRANT SELECT ON mydb.*)只在
mydb这个库内有效,哪怕之后新建了
otherdb,该用户也无权访问。
CREATE DATABASE 权限必须在全局级别授予
即使你给用户授予了
mydb的全部权限(
GRANT ALL ON mydb.*),他依然不能执行
CREATE DATABASE otherdb。因为
CREATE DATABASE是一个需要
CREATE全局权限的操作——它不作用于某个具体库,而是影响服务器元数据。常见误操作是以为“有了库级
ALL就能建库”,结果报错:
ERROR 1044 (42000): Access denied for user ... to database 'otherdb'。
GRANT CREATE ON *.* TO 'u'@'%'✅ 允许创建任意新库
GRANT CREATE ON mydb.* TO 'u'@'%'❌ 不起作用,MySQL 忽略该授权 同理,
DROP DATABASE、
SHOW DATABASES也都依赖全局权限
权限叠加时,全局权限优先级高于数据库级
如果一个用户同时拥有全局
SELECT和某个库的
REVOKE SELECT,最终仍可查该库——因为全局权限未被显式收回,且覆盖更细粒度的拒绝。MySQL 权限检查顺序是:全局 → 数据库 → 表 → 列,只要某一层允许,就通过(除非被更上层显式拒绝)。这意味着: 撤销权限必须在相同作用域执行,
REVOKE SELECT ON mydb.*无法取消
SELECT ON *.*
SHOW GRANTS FOR 'u'@'%'返回的结果里,
*.*条目会出现在
mydb.*前面,反映检查顺序 用
FLUSH PRIVILEGES不解决权限不生效问题,真正生效靠的是权限表(
mysql.user,
mysql.db)的实时读取
mysqldump 备份时容易暴露权限设计缺陷
用
mysqldump --all-databases要求用户有全局
SELECT和
LOCK TABLES,但很多人只给了目标库权限,导致备份中途失败。更隐蔽的问题是:如果用户只有
mydb.*权限,却尝试
mysqldump --databases mydb otherdb,MySQL 会拒绝导出
otherdb(即使它存在),并报错
Access denied for user ... to database 'otherdb'——这不是连接问题,是权限校验在 dump 阶段逐库触发的。
mysqldump -u backup_user -p --databases mydb otherdb # 如果 backup_user 没有 otherdb.* 或 *.* 权限,这里就会中断
实际部署中,别默认“给库权限就够了”,先想清楚操作是否跨库、是否涉及元数据变更。权限最小化原则在这里特别容易被绕过,因为看起来只是“少建一个库”或“少导一个库”,背后其实是权限模型的层级刚性。
