必须显式授予目标schema库级权限(如on myapp_db.*),否则use虽成功但后续操作报“unknown database”;show databases也不显示该库,因mysql仅在dml/dql时校验权限且过滤无权数据库。

必须给用户显式授予目标 Schema 的库级权限,否则 USE 会静默失败,SHOW DATABASES 也看不到库名——这不是连接问题,是权限配置缺位。
为什么 USE myapp_db 执行成功但后续语句报错“Unknown database”
常见现象:用户执行 USE myapp_db 返回 Query OK,但紧接着 SELECT * FROM users 报错 ERROR 1049 (42000): Unknown database 'myapp_db'。
根本原因不是语法或拼写错误,而是该用户对 myapp_db 没有任何实际权限(哪怕只读)。MySQL 允许你执行 USE,但后续所有操作都会因无权限被拒绝,且错误提示误导性极强。
-
USE本身不校验权限,只检查库是否存在、当前用户能否连接 - 真正触发权限校验的是第一个 DML/DQL 操作(如
SELECT、INSERT) - 若用户对
myapp_db完全没授过权,SHOW DATABASES也不会列出它(除非配置了skip-show-databases=OFF且用户有其他库权限)
GRANT 必须包含库名和通配符,不能只写 myapp_db
错误写法:GRANT SELECT ON myapp_db TO 'app_user'@'localhost' —— 这会报错 ERROR 1144 (42000): Illegal GRANT/REVOKE command,因为 MySQL 要求库级权限必须带 .*。
正确写法只有两种:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 授予整个库所有表:
GRANT SELECT, INSERT ON myapp_db.* TO 'app_user'@'localhost' - 只授某张表:
GRANT UPDATE ON myapp_db.users TO 'app_user'@'localhost'
注意:GRANT USAGE ON myapp_db.* 是无效的——USAGE 是空权限,只允许连接,不解决 USE 后的访问问题。
用户登录后仍看不到目标 Schema?检查两个硬性条件
SHOW DATABASES 不显示 myapp_db,通常不是授权没生效,而是以下任一条件未满足:
- MySQL 配置中启用了
skip-show-databases(需在my.cnf中确认并设为OFF) - 用户对
myapp_db没有任何显式权限(哪怕SELECT也不行),导致 MySQL 自动过滤掉该库
验证方式:
- 用 root 执行
SELECT host,user,db,privilege_type FROM mysql.schema_privileges WHERE user='app_user' AND db='myapp_db';确认记录存在 - 用
app_user登录后,直接执行SELECT 1 FROM myapp_db.users LIMIT 1;—— 如果能返回结果,说明权限已生效,SHOW DATABASES不显示只是显示策略问题
应用代码里切换 Schema 的安全实践
不要依赖客户端自动缓存 Schema 名,每次操作前显式指定库名或执行 USE。尤其在连接池场景下,连接复用可能导致 Schema 上下文残留。
- 推荐写法:
SELECT * FROM myapp_db.users(显式带库名) - 次选写法:在事务开头执行
USE myapp_db,且确保该语句与后续 SQL 在同一连接内 - 避免在长连接中频繁切换 Schema,容易引发权限混淆或元数据缓存不一致
复杂点在于:MySQL 的权限校验发生在语句解析阶段,不是连接建立时。一个用户可能对 db_a 有 SELECT 权限、对 db_b 有 INSERT 权限,但只要没授过 db_c 的任何权限,USE db_c 就永远无法真正“激活”它——这点容易被忽略,直到应用报出难以定位的 Unknown database 错误。










