MySQL 8.0中直接GRANT KILL权限会失败,因KILL操作需CONNECTION_ADMIN(发KILL命令)与PROCESS(查看线程ID)两个动态权限组合,且必须全局授予ON .,二者均不被ALL PRIVILEGES覆盖,host匹配须严格一致,FLUSH PRIVILEGES对动态权限无效。

为什么直接 GRANT KILL 权限会失败
MySQL 8.0 中已移除对 KILL 操作的隐式支持,也不再通过 SUPER 授予。执行 KILL 12345 报错 ERROR 1227 (42000): Access denied,即使用户有 ALL PRIVILEGES,也大概率是因为缺少 CONNECTION_ADMIN——它不属于静态权限集,不会被 ALL 覆盖。
必须用 CONNECTION_ADMIN + PROCESS 组合授权
单独 CONNECTION_ADMIN 只能发 KILL 命令,但无法看到目标线程 ID;没有 PROCESS,连 SHOW PROCESSLIST 都被拒绝,实际无法定位要杀的连接。
-
GRANT CONNECTION_ADMIN ON *.* TO 'monitor'@'10.20.%'—— 必须是全局层级,ON app_db.*语法非法 -
GRANT PROCESS ON *.* TO 'monitor'@'10.20.%'—— 同样只能在*.*层级授予 - 授完不重连,权限不会生效;
FLUSH PRIVILEGES对动态权限无效
host 匹配不严会导致 KILL 静默失败
即使权限全给了,KILL 仍可能没反应或报错,常见原因是当前用户与被杀线程的 host 不满足 MySQL 的匹配逻辑:
- 你用
'monitor'@'10.20.%'登录,能杀'app_user'@'192.168.5.%'的连接(不同网段没关系) - 但若被杀的是
'app_user'@'localhost',而你没显式创建并授权'monitor'@'localhost',就会失败 -
CURRENT_USER()返回值必须和授权时的 host 完全一致,USER()不参与权限校验
验证是否真能 KILL,别信 SHOW GRANTS
SHOW GRANTS FOR 'monitor'@'10.20.%' 只显示直授权限,不展开动态权限是否就绪。最可靠验证方式是实测:
- 会话 A:执行
SELECT SLEEP(300),记下CONNECTION_ID() - 会话 B(用 monitor 用户):查
SHOW PROCESSLIST找到该 ID,执行KILL [id] - 立刻切回会话 A:若中断并报
ERROR 2013 (HY000): Lost connection...,说明成功 - 更准的观察点是查
performance_schema.threads表,看对应线程的PROCESSLIST_STATE是否变Idle或消失
中间件(如 ProxySQL)、require_secure_transport=ON、认证插件差异都可能拦截 KILL,这些点容易漏掉,得逐个排除。


















