直接授予所有库select权限会误触系统库和敏感库,应手动筛选业务库逐条授权,并注意反引号、flush privileges及视图定义者权限风险。

直接给所有库授 SELECT 权限会误触系统库和敏感库
用 GRANT SELECT ON *.* TO 'analyst'@'%' 看似省事,但实际会把 mysql、information_schema、performance_schema、sys 这些系统库也包含进去。分析师查这些库不仅没意义,还可能暴露用户密码哈希、权限配置等高危信息;更严重的是,某些版本(如 MySQL 8.0+)对系统库的访问有隐式限制,导致查询报错或权限校验异常。
手动筛选业务库并逐条授权才是安全做法
核心思路是:只对明确属于业务用途的库授 SELECT,跳过所有已知敏感前缀库。实操分三步:
- 先查出当前所有非系统库:
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys', 'audit_log');(注意加上audit_log,部分企业启用了审计插件) - 对每个库生成授权语句,库名必须加反引号:
GRANT SELECT ON `order_db`.* TO 'analyst'@'%';—— 不加反引号时,若库名含短横线(如crm-v2)会语法报错 - 执行完所有
GRANT后,必须运行FLUSH PRIVILEGES;,尤其在 MySQL 5.7 或未启用skip-grant-tables的实例上,否则权限不生效
MySQL 8.0.16+ 推荐用角色批量管理
如果业务库数量多、变动频繁(比如每月新增 1–2 个),硬编码每条 GRANT 很难维护。角色(ROLE)能解耦权限定义与用户绑定:
- 创建角色:
CREATE ROLE 'analyst_role'; - 给角色授业务库权限(同样需手动列库):
GRANT SELECT ON `sales_db`.* TO 'analyst_role'; GRANT SELECT ON `user_db`.* TO 'analyst_role'; - 再把角色赋给用户:
GRANT 'analyst_role' TO 'analyst'@'%'; - 后续增删库,只需更新角色权限,无需碰用户本身
容易被忽略的权限继承细节
即使你只授了 SELECT,分析师仍可能通过视图间接读到不该看的数据——前提是视图定义者(DEFINER)权限过高,且视图没做字段过滤。例如一个由 root 创建的视图 v_user_full 包含明文身份证字段,哪怕分析师只有 SELECT 权限,也能查出来。所以真正要防的不是库级授权,而是视图/函数的定义者权限和逻辑脱敏是否到位。











