必须授予全局RELOAD权限才能执行FLUSH类命令,因MySQL将所有FLUSH操作统一收口于此权限,不提供更细粒度选项;该权限需ON .显式授予,且仅限专用账号与受限IP,因其可触发锁阻塞、提权链等高危行为。

必须授予全局 RELOAD 权限,才能让用户执行 FLUSH 类命令(包括刷新查询缓存、日志、表等);MySQL 不提供更细粒度的“仅刷新缓存”权限。
为什么 RELOAD 是唯一可行选项
MySQL 的权限模型把所有 FLUSH 操作(FLUSH LOGS、FLUSH TABLES、FLUSH QUERY CACHE、FLUSH HOSTS 等)统一收口在全局 RELOAD 权限下。这不是遗漏,是设计如此:
- 没有
FLUSH_CACHE、FLUSH_LOGS_ONLY这类独立权限 - 试图用
GRANT ... ON mysql.*或ON mydb.*授予RELOAD会静默失败——它只接受ON *.* - 执行
FLUSH QUERY CACHE时若缺RELOAD,报错固定为:ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
如何安全授予 RELOAD 权限
最小化暴露面是关键。别跳过 IP 限制和账号专用性:
- 用高权限账号(如
root)登录后执行:GRANT RELOAD ON *.* TO 'cache_admin'@'10.20.30.%' - 立即生效需运行:
FLUSH PRIVILEGES(注意:仅当直接改表才必须;用GRANT语句本身已触发重载,但加一句无害且可确认) - 验证是否生效:
SHOW GRANTS FOR 'cache_admin'@'10.20.30.%'—— 输出里必须含RELOAD字样 - 禁止用
'%'代替具体网段,也别绑定到'localhost'后又通过 SSH 隧道绕过——这等于开放给任意本地进程
RELOAD 带来的实际风险点
它不止能刷缓存,还能干这些事,而多数人只关注目标操作:
-
FLUSH TABLES:可能引发长持有锁,阻塞写入 -
FLUSH PRIVILEGES:若配合其他漏洞(如可写系统表),可能成为提权链一环 -
FLUSH HOSTS:清空host_cache,可被用于绕过连接拒绝策略 -
FLUSH ENGINE LOGS:影响 InnoDB 崩溃恢复一致性检查点
所以绝不能把 RELOAD 给应用账号、开发账号或共享运维账号。只配给监控脚本专用账号,且该账号密码一旦泄露,就等于给了攻击者一个轻量级 DBA 入口。
有没有真正安全的替代方案
没有零风险的替代,但可降维管控:
- 用
mysqladmin -u root flush-query-cache+sudo免密配置,把执行权交给 OS 用户而非 MySQL 用户 - MySQL ≥ 8.0.16 可建
SQL SECURITY DEFINER存储过程封装FLUSH QUERY CACHE,再授EXECUTE权限——但过程必须由root创建,且无法防住过程内嵌恶意逻辑 - 代理层拦截重写(如 ProxySQL)太重,只为一个命令不值得
真正容易被忽略的是:哪怕你只开了一个 CIDR 段的 RELOAD,只要那个账号密码落在日志、配置文件或开发者本地环境里,权限就等同于裸奔。


















