mysql中数据库用户的只读与读写权限设置

1次阅读

mysql中授予用户只读权限需显式执行grant select on db_name.* to ‘user’@’host’,禁用grant option,避免误用usage;读写权限则授select,insert,update,delete,禁用all privileges及高危权限。

mysql中数据库用户的只读与读写权限设置

MySQL 中如何授予用户只读权限

只读权限意味着用户只能执行 SELECT,不能修改数据或结构。最稳妥的做法是显式授予 SELECT 权限,且不授予其他 DML 或 DDL 权限。

常见错误是误用 USAGE(它实际表示“无任何权限”,不是只读)或遗漏 GRANT OPTION 的禁用(否则用户可能自行授权他人)。

  • 对单个数据库授只读:使用 GRANT SELECT ON `db_name`.* TO 'user'@'host';
  • 若需跨库只读,需为每个库单独执行 GRANT SELECT;MySQL 不支持通配多个库名
  • 执行后必须运行 FLUSH PRIVILEGES;(仅在直接操作 mysql 系统表后才强制需要;通过 GRANT 语句赋权通常自动生效,但部分旧版本或特殊部署建议刷新)
  • 注意:视图、存储过程等对象的访问还取决于其定义者权限和 SQL SECURITY 设置,SELECT 权限本身不自动覆盖这些

MySQL 中如何授予用户读写权限

读写权限一般指允许 SELECTINSERTUPDATEDELETE,但不含结构变更(如 CREATEDROP)。这是应用账号最常见的最小权限模型。

不要直接授予 ALL PRIVILEGES —— 它包含 GRANT OPTIONALTER ROUTINEFILE 等高危权限,极易引发越权或安全风险。

  • 标准读写(不含建表/删表):GRANT SELECT, INSERT, UPDATE, DELETE ON `db_name`.* TO 'user'@'host';
  • 如果应用需要清空表(TRUNCATE),注意:MySQL 中 TRUNCATE 需要 DROP 权限(因其本质是删表重建),不是 DELETE 权限能覆盖的
  • 若业务涉及临时表(如子查询物化),还需额外授予 CREATE TEMPORARY TABLES 权限
  • 权限作用域尽量精确到库(`db_name`.*),避免用 *.* ;生产环境禁止对 mysql 系统库授任何非 dba 用户权限

撤销权限与检查当前权限

权限变更后,务必验证是否生效。MySQL 不会自动回收已存在的活跃连接的权限缓存,旧连接仍持有赋权前的权限快照,需重新登录或等待连接复用失效。

  • 撤销某类权限:REVOKE INSERT, UPDATE ON `db_name`.* FROM 'user'@'host';(注意:不是 DROP,而是 REVOKE
  • 查看用户所有权限:SHOW GRANTS for 'user'@'host';
  • 查看当前会话权限:SHOW PRIVILEGES; 不显示当前用户权限,应改用 SELECT * FROM INFORMATION_SCHEMA.ROLE_TABLE_GRANTS;(8.0+)或更直接的方式:SELECT CURRENT_USER(), USER(); + SHOW GRANTS;
  • 权限继承关系复杂:角色(8.0+)可简化管理,但若用角色,需确认用户已 SET default ROLE,否则角色权限不会激活

常见权限相关错误与绕过风险

权限配置看似简单,但几个关键点容易被忽略,导致“以为限制了,其实没生效”:

  • localhost127.0.0.1 在 MySQL 中被视为不同 host —— 用户 'user'@'localhost''user'@'127.0.0.1' 是两个独立账户,权限需分别设置
  • 通配符主机名(如 'user'@'%')优先级低于具体 IP,但若存在 'user'@'192.168.1.%''user'@'%',MySQL 按最长匹配原则选择,不是按书写顺序
  • 即使用户只有 SELECT 权限,若其能访问 INFORMATION_SCHEMA(默认所有用户可查),就能枚举库表结构;如需进一步收敛,需用 --skip-show-database 启动参数或限制 SHOW DATABASES 权限(8.0.12+ 支持 SHOW DATABASES 权限开关)
  • 函数/存储过程执行权限独立于表权限:即使用户无 SELECT 权限,只要拥有 EXECUTE 权限且过程定义为 SQL SECURITY DEFINER,就可能间接读取数据 —— 这是典型的权限绕过场景

权限粒度控制在 MySQL 里不是一劳永逸的事,尤其当引入视图、过程、事件或复制拓扑时,权限上下文会动态变化。上线前最好用目标用户账号实际执行一遍典型 SQL 流程,而不是只依赖 SHOW GRANTS 输出判断。

text=ZqhQzanResources