GRANT语句未指定具体数据库导致权限未生效,需确认目标库存在、用户有对应库级CREATE权限、连接时USE目标库或写全表名,并检查角色、REVOKE及FLUSH PRIVILEGES是否遗漏。

GRANT 语句没指定具体数据库,权限实际未生效
很多人执行了 GRANT CREATE ON *.* TO 'user'@'host',但误以为对某个特定库授了权;或者更常见的是,只写了 GRANT CREATE ON database_name.*,却忘了用户当前根本没 USE 这个库,甚至该库都不存在。MySQL 的权限检查是“库级 + 操作级”双校验:既要该用户在目标库上有 CREATE 权限,也要该库真实存在且用户能访问它。
- 执行
SHOW DATABASES确认目标库是否存在;不存在就先CREATE DATABASE database_name - 用
SHOW GRANTS FOR 'user'@'host'查权限——注意看输出里是否真有GRANT CREATE ON `database_name`.*这一行,而不是GRANT CREATE ON *.*或GRANT CREATE ON `other_db`.* - 如果用的是通配符(比如
myapp_%),确认库名严格匹配模式,MySQL 不支持模糊匹配或正则
用户连接时没显式指定数据库,导致 CREATE TABLE 被拒绝
MySQL 在执行 CREATE TABLE t1(...) 时,如果当前 session 没通过 USE database_name 切换到目标库,且 SQL 中又没写库名前缀(如 database_name.t1),服务器会默认尝试在“当前默认库”里建表。而这个默认库很可能为空、不存在,或用户对该库无任何权限。
- 错误现象:
ERROR 1046 (3D000): No database selected或ERROR 1142 (42000): CREATE command denied to user ... for table 't1' - 正确做法:要么先
USE database_name,再执行CREATE TABLE t1(...);要么直接写全名CREATE TABLE database_name.t1(...) - 注意:即使用户对
database_name有CREATE权限,若没USAGE(即连接权)或SELECT(部分版本要求),USE命令本身也会失败
权限被 WITH GRANT OPTION 或角色覆盖,实际被隐式撤销
MySQL 8.0+ 引入了角色(ROLE)和更细粒度的权限继承机制,而旧版 MySQL(5.7)中,如果用户被赋予了多个 GRANT 语句,后执行的 REVOKE 或冲突的 GRANT 可能覆盖前面的设置。尤其要注意:用 GRANT ALL PRIVILEGES 并不自动包含 CREATE,除非明确声明或使用 GRANT ALL ON database_name.*。
-
GRANT ALL ON *.*和GRANT ALL ON database_name.*权限范围不同:前者含全局权限(如CREATE USER),后者才是库级操作权限 - 检查是否有
REVOKE CREATE ON database_name.* FROM 'user'@'host'曾被执行过,哪怕是一次性调试命令 - MySQL 8.0+ 用户可能被分配了角色,而角色没包含
CREATE——查SELECT * FROM mysql.role_edges WHERE TO_HOST = 'host' AND TO_USER = 'user';,再查对应角色的权限
FLUSH PRIVILEGES 被忽略,或权限缓存未更新
大多数情况下,GRANT 后无需手动 FLUSH PRIVILEGES(MySQL 5.7.6+ 自动刷新),但如果修改的是底层权限表(如直接 UPDATE mysql.tables_priv),或者用的是旧版本 MySQL,遗漏这步会导致权限长期不生效。
- 执行
GRANT CREATE ON database_name.* TO 'user'@'host';后,立刻用同一个连接执行SHOW GRANTS FOR CURRENT_USER();——如果看不到刚授的权限,说明没生效 - 此时必须执行
FLUSH PRIVILEGES;(仅当直接改系统表或旧版本才真正需要) - 更稳妥的做法:断开重连,因为权限只在新连接中加载;不要依赖当前连接复用旧权限上下文
复杂点在于权限不是“开关式”的——它由 host、user、db、table 四层匹配,任意一层不满足都会拒绝。最容易被忽略的是:你以为授了权的库,其实用户连 USE 都进不去;或者你授的是 CREATE,但建表语句里用了 ENGINE=InnoDB,而用户没被授予 INNODB 相关权限(极少见,但某些严格配置下会触发)。


















