mysql中的全局权限与数据库级权限的差异

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

全局权限能跨库操作,数据库级权限只能作用于指定库

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.* 或 *.* 权限,这里就会中断

实际部署中,别默认“给库权限就够了”,先想清楚操作是否跨库、是否涉及元数据变更。权限最小化原则在这里特别容易被绕过,因为看起来只是“少建一个库”或“少导一个库”,背后其实是权限模型的层级刚性。

相关推荐