GRANT 是什么
GRANT 为已有账号授予权限,语法是 GRANT 权限列表 ON 对象 TO '用户'@'主机'。对象粒度分全局、库级、表级、列级和例程级,权限范围依次收窄。核心原则是最小权限:业务账号只给需要的增删改查,只读账号只给查询,管理类权限单独管理。8.0 里授权不再隐式创建账号,账号与库表必须事先存在,授权后立即生效,不需要手动刷新。
基本信息
| 用途 | 为已有账号授予权限 |
|---|---|
| 语法 | GRANT 权限列表 ON 对象 TO '用户'@'主机' [WITH GRANT OPTION] |
| 授权粒度 | 全局 *.* / 库 db.* / 表 db.tbl / 列 / 例程 |
| 常用权限 | SELECT INSERT UPDATE DELETE CREATE DROP ALTER INDEX EXECUTE |
| 生效时机 | 8.0 授权后立即生效,无需刷新权限 |
| 配套操作 | SHOW GRANTS 查看,REVOKE 回收 |
典型使用场景
- 应用账号按库授权:业务库给增删改查,不碰其他库
- 只读账号只给查询:报表与监控使用,杜绝误改数据
- 列级授权:敏感表只开放部分字段给分析人员
- 例程授权:只允许调用某个存储过程,不直接开放表访问
- 上线初期临时给建表权限,交付前统一收回
- 权限审计:导出各账号授权清单做最小权限核对
分层授权示例
分层授权示例
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'10.0.%'; # 库级增删改查
GRANT SELECT ON appdb.orders TO 'readonly'@'%'; # 表级只读
GRANT SELECT(id, sku, qty) ON appdb.order_items TO 'analyst'@'%'; # 列级授权
GRANT EXECUTE ON PROCEDURE appdb.sp_close_orders TO 'ops'@'localhost'; # 例程授权查看与回收
查看与回收
SHOW GRANTS FOR 'app'@'10.0.%'; # 查看指定账号的授权
SHOW GRANTS FOR CURRENT_USER(); # 查看当前登录账号
REVOKE DELETE ON appdb.* FROM 'app'@'10.0.%'; # 回收单项权限
FLUSH PRIVILEGES; # 只有直接修改授权表时才需要授权粒度对照
| 对象写法 | 范围 | 典型用途 |
|---|---|---|
| *.* | 全局权限 | 管理账号与备份账号,业务账号禁用 |
| db.* | 整个库 | 应用账号的标准粒度 |
| db.tbl | 单张表 | 只读报表或限定对象访问 |
| db.tbl (列清单) | 指定列 | 敏感字段隔离与脱敏场景 |
| PROCEDURE db.sp | 单个例程 | 只开放调用入口 |
| WITH GRANT OPTION | 允许被授权者继续转授 | 除集中管理场景外不建议开启 |
全局所有权限等同于超级权限,业务账号绝不能这样授;转授权选项允许被授权方继续把权限分发给别人,除集中管理场景外都应关闭。
8.0 起授权对象必须先存在:给不存在的库表授权会直接报错,也不会像旧版本那样顺带创建账号,建账号与授权是明确的两步操作。
授权之后立即生效,不需要刷新权限表;只有绕过账号管理语句直接改授权系统表、又希望马上生效时,才需要显式刷新。
最小权限落地清单
- 先明确账号用途,再决定需要哪几类权限
- 能用库级就不给全局,能用表级就不给库级
- 写权限与删除权限分开评估,删除权限单独收紧
- 管理类权限只给运维专用账号,业务账号一律不给
- 定期导出授权清单核对,回收不再使用的权限
- 高权限账号的敏感操作要留存审计记录
授权是按用户名加来源主机组合生效的:给 'app'@'%' 授了权限,不会自动覆盖到 'app'@'10.0.%' 这条记录,授权前先确认账号清单里到底有哪几条身份。
授权前先核对账号
授权前先核对账号
SELECT user, host FROM mysql.user WHERE user='app'; # 列出该用户名下的所有来源
SHOW GRANTS FOR 'app'@'10.0.%'; # 确认这条身份当前有哪些授权
REVOKE ALL PRIVILEGES ON appdb.* FROM 'app'@'10.0.%'; # 重建授权前先清空,避免旧权限残留