基于 MySQL 8.0 细粒度授权:单独授予 KILL 权限的优雅解决方案 ...

打印 上一主题 下一主题

主题 1042|帖子 1042|积分 3126

基于 MySQL 8.0 细粒度授权:单独授予 KILL 权限的优雅解决方案


一、引言

作为一名数据库从业者,我在日常工作中常常会遇到一个棘手的问题:如何在保证安全的条件下,让业务团队拥有足够的权限去管理数据库实行的 SQL,尤其是停止那些失控的慢查询或异常线程?这个问题看似简单,却扳连到权限计划、安全合规以及数据库稳定性等多方面的权衡。今天,我们就来聊聊 MySQL 8.0 如何通过权限体系的革新,特别是对 KILL 权限的细化支持,解决了这一痛点,并为 DBA 和业务开发团队带来了更大的机动性。
二、从痛点说起:KILL SQL 的权限困境

在 MySQL 实际利用中,业务开发职员常希望拥有停止 SQL 的能力。比方,慢查询占用大量资源,或未优化的批量操作导致负载飙升,此时及时 KILL 问题 SQL 是最直接的解决办法。然而,MySQL 的权限计划限定让这一需求难以实现,开发职员往往只能依赖 DBA 操作,既低效又拖延响应。
在 MySQL 的传统版本(比如 5.7 及更早版本)中,KILL 权限的实现存在以下几个问题:

  • 实行用户限定 默认情况下,用户只能 KILL 自己创建的线程。若业务程序利用统一账号(如 app_user),开发职员想通过此账号停止 SQL,必须知道其暗码并登录数据库实行 KILL。然而,企业安全规范通常克制程序账号单点登录,因其权限过大(至少包罗增删改查),导致开发职员无法直接操作。这形成了一个"权限死结":想 KILL 无权限,有权限却无法登录。
  • SUPER 权限过大 为突破上述限定,允许用户 KILL 其他用户的 SQL,需授予 SUPER 权限。这看似可行,但 SUPER 权限是个“大杀器”:持有者不仅能 KILL 任何线程,还可修改全局参数(如 innodb_buffer_pool_size)、实行 STOP GROUP_REPLICATION 关闭组复制等操作(甚至会导致中断服务)。此权限通常仅限超等管理员利用,对业务开发而言明显过大,且存在严峻安全隐患,DBA 自然不肯授予业务团队。
面对这样的困境,我们不禁会问:难道就没有一个一箭双雕的办法,既能让业务团队有 KILL SQL 的能力,又不至于权限失控吗?
答案是肯定的,MySQL 8.0 的到来,让这一需求成为了现实。
三、MySQL 8.0 的细粒度权限拆分:KILL 权限独立登场

MySQL 8.0 在权限体系上迎来重大改进,最显著的是对 SUPER 权限的拆分。在 5.7 及之前,SUPER 权限如同一个大包袱,功能过于繁芜。而 8.0 引入了动态权限(即运行时可分配的细化权限),将 SUPER 拆解为多个细粒度权限,其详细内容如下:
权限名解释影响的部分MySQL5.7命令示例SYSTEM_VARIABLES_ADMIN允许在运行时更改全局系统变量,包罗利用 SET GLOBAL 和 SET PERSIST,以及更改全局事务特性。SET GLOBAL innodb_buffer_pool_size = 268435456;
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;SESSION_VARIABLES_ADMIN允许设置需要特别权限的受限会话系统变量。SET SESSION sql_log_bin = 0;REPLICATION_SLAVE_ADMIN允许启动和制止常规复制,利用 CHANGE REPLICATION SOURCE TO、CHANGE MASTER TO 等语句。CHANGE MASTER TO MASTER_HOST='replica_host';GROUP_REPLICATION_ADMIN允许启动和制止组复制(Group Replication)。START GROUP_REPLICATION;BINLOG_ADMIN允许通过 PURGE BINARY LOGS 和 BINLOG 语句控制二进制日记。PURGE BINARY LOGS TO 'mysql-bin.000010';SET_USER_ID允许在视图或存储程序的 DEFINER 属性中指定任何账户作为有效授权 ID。CREATE DEFINER='admin'@'[localhost](http://localhost)' VIEW v1 AS ...;CONNECTION_ADMIN控制客户端毗连行为,包罗停止其他账户线程、绕过毗连限定、离线模式毗连和读写操作等。KILL 12345;ENCRYPTION_KEY_ADMIN启用 InnoDB 加密密钥轮换。(无直接命令,通常涉及加密相干配置)VERSION_TOKEN_ADMIN允许实行版本令牌(Version Tokens)功能。(涉及特定插件,如 version_tokens_lock() 函数)ROLE_ADMIN允许授予和撤销脚色、利用 WITH ADMIN OPTION 和 ROLES_GRAPHML() 函数。(MySQL5.7 没有 role 功能,不涉及)SUPER 被拆分为 10 个动态权限。同时,MySQL 8.0 因新增功能和组件,又引入了 29 个动态权限,构成以下 39 个动态权限列表:
权限级别解释是否为 SUPER 拆出APPLICATION_PASSWORD_ADMIN全局启用双暗码管理。AUDIT_ABORT_EXEMPT全局允许审计日记过滤器阻止的查询继续实行。AUDIT_ADMIN全局启用审计日记配置。AUTHENTICATION_POLICY_ADMIN全局启用认证策略管理。BACKUP_ADMIN全局启用备份管理。BINLOG_ADMIN全局启用二进制日记控制。是BINLOG_ENCRYPTION_ADMIN全局启用二进制日记加密的激活和停用。CLONE_ADMIN全局启用克隆管理。CONNECTION_ADMIN全局启用毗连限定/控制。是ENCRYPTION_KEY_ADMIN全局启用 InnoDB 密钥轮换。是FIREWALL_ADMIN全局启用防火墙规则管理(任何用户)。FIREWALL_EXEMPT全局豁免用户免受防火墙限定。FIREWALL_USER全局启用防火墙规则管理(自身)。FLUSH_OPTIMIZER_COSTS全局启用优化器成本重新加载。FLUSH_STATUS全局启用状态指示器刷新。FLUSH_TABLES全局启用表刷新。FLUSH_USER_RESOURCES全局启用用户资源刷新。GROUP_REPLICATION_ADMIN全局启用组复制控制。是INNODB_REDO_LOG_ARCHIVE全局启用重做日记归档管理。INNODB_REDO_LOG_ENABLE全局启用或禁用重做日记记录。NDB_STORED_USER全局启用在 SQL 节点间共享用户或脚色(NDB 集群)。PASSWORDLESS_USER_ADMIN全局启用无暗码用户账户管理。PERSIST_RO_VARIABLES_ADMIN全局启用持久化只读系统变量。REPLICATION_APPLIER全局作为复制通道的 PRIVILEGE_CHECKS_USER 脚色。REPLICATION_SLAVE_ADMIN全局启用常规复制控制。是RESOURCE_GROUP_ADMIN全局启用资源组管理。RESOURCE_GROUP_USER全局启用资源组管理(用户级别)。ROLE_ADMIN全局启用脚色授予或撤销,利用 WITH ADMIN OPTION。是SESSION_VARIABLES_ADMIN全局启用设置受限会话系统变量。是SET_USER_ID全局启用设置非自身 DEFINER 值。是SHOW_ROUTINE全局启用访问存储过程界说。SKIP_QUERY_REWRITE全局不重写此用户实行的查询。SYSTEM_USER全局将账户指定为系统账户。SYSTEM_VARIABLES_ADMIN全局启用修改或持久化全局系统变量。是TABLE_ENCRYPTION_ADMIN全局启用覆盖默认加密设置。TELEMETRY_LOG_ADMIN全局启用 HeatWave on AWS 的遥测日记配置。TP_CONNECTION_ADMIN全局启用线程池毗连管理。VERSION_TOKEN_ADMIN全局启用版本令牌函数的利用。是XA_RECOVER_ADMIN全局启用 XA RECOVER 实行。其中,KILL SQL 可以利用 CONNECTION_ADMIN这个动态权限来单独授权。
SUPER 因权限过大的安全隐患,在 8.0 版本开始已经不发起利用。官方文档明白指出,SUPER 已被标志为即将废弃,保举尽早迁移至动态权限体系。
SUPER is a powerful and far-reaching privilege and should not be granted lightly. If an account needs to perform only a subset of SUPER operations, it may be possible to achieve the desired privilege set by instead granting one or more dynamic privileges, each of which confers more limited capabilities. See Dynamic Privilege Descriptions.
Note
SUPER is deprecated, and you should expect it to be removed in a future version of MySQL. See Migrating Accounts from SUPER to Dynamic Privileges.
详细到 KILL SQL 的场景,还有一些细节要留意,如果开发或业务 DBA 需要 KILL SQL,除了需要刚才讨论的 CONNECTION_ADMIN 权限外,还有一个条件,要求能看到对应的线程,这要求授予 PROCESS 权限,这样他实行 show processlist 时就可以看到所有用户运行的线程了,而非只能看到自己的线程。这个权限 5.7、8.0 通用,允许用户查看其他用户的线程,授权如下:
  1. GRANT PROCESS ON *.* TO 'dev_admin';
复制代码
留意,PROCESS 权限允许查看他人 SQL 原文,大概导致敏感信息泄漏。发起业务部门自行评估安全风险,比方仅授权高级业务 DBA 查看全局 SHOW PROCESSLIST 并实行 KILL SQL。
拥有 PROCESS 权限的用户可按以下步骤停止问题线程:

  • 实行 SHOW PROCESSLIST; 查看运行线程列表,找到目的线程 ID。( 对应 PROCESS 权限 )
  • 实行 KILL ; 停止指定线程。( 对应CONNECTION_ADMIN 权限 )  比方:
  1. SHOW PROCESSLIST;
  2. KILL 12345;
复制代码
这样一来,业务团队就拥有了停止恣意 SQL 的能力,而 DBA 也不必担心他们会误操作全局参数或关闭服务器。权限控制变得更加精细,安全性和机动性得到了分身。
四、系统线程的安全防护:SYSTEM_USER 权限的加持

然而,仔细的读者大概会提出一个问题:如果用户拥有了 PROCESS 权限,他们会不会一不小心 KILL 掉一些关键的系统线程,比如主从复制线程(Replication Thread)或后台维护线程?这确实是一个公道的担忧,因为系统线程一旦被误杀,大概会导致数据库服务中断,甚至引发数据不同等的风险。
MySQL 8.0 的计划者显然也考虑到了这一点。为了保护系统线程,他们引入了 SYSTEM_USER 权限。这个权限的作用是区分平凡用户线程和系统线程,并为后者提供额外的保护。详细规则如下:

  • 如果某个线程是由具有 SYSTEM_USER 权限的用户创建的(通常是 MySQL 的内置系统账号,比如复制线程的实行用户),那么平凡用户(没有 SYSTEM_USER 权限)无法通过 KILL 命令停止它。
  • 只有当前会话也具备 SYSTEM_USER 权限的用户,才能 KILL 掉同样具备 SYSTEM_USER 权限的线程。
这意味着,即便业务用户拥有了 PROCESS 权限,他们也无法干扰数据库的后台线程,比如主从复制线程、事件调理线程(Event Scheduler)或管理员的命令行。这种计划极大地提拔了系统的稳定性,避免了权限滥用带来的潜伏风险。
这就保证了平凡用户无法越界操作,系统的焦点功能得到了保护。
五、实战演练:如何优雅地利用 KILL 权限

1. 利用 dbops 搭建一主两从的 MySQL8.0.41 实例

dbops 是什么,见 http://dbops.cn
2. 创建程序账号 app_user,授予业务库 app_db 的增删改查权限
  1. create user app_user identified by 'Dbops@2025';
  2. grant select,insert,update,delete on `app\_db`.* to app_user;
复制代码
3. 创建业务库、业务表,并实行长事务



4. 创建开发主管账号 dev_admin,授予查看全局 SQL 和 KILL SQL 权限
  1. create user 'dev_admin' identified by 'Dbops@2025';
  2. GRANT PROCESS ON *.* TO 'dev_admin';
  3. GRANT CONNECTION_ADMIN ON *.* TO 'dev_admin';
复制代码
5. 为后台线程账号(如 admin、repl)授予 SYSTEM_USER 权限,标志为受保护线程,平凡用户无法 KILL
  1. GRANT SYSTEM_USER on *.* to admin@'127.0.0.1';
  2. GRANT SYSTEM_USER on *.* to admin@'localhost';
  3. GRANT SYSTEM_USER on *.* to repl@'1%';
复制代码
随后,重启复制线程,重新毗连admin命令行窗口,让权限生效。
6. 测试 KILL SQL

受 SYSTEM_USER 保护的线程无法被停止。

而平凡用户(如 app_user)的线程可被停止。

留意事项
在 MySQL 8.0 中,权限不敷的错误信息因操作而异。比方,修改全局变量时:
  1. mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  2. ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
复制代码
这明白指出所需权限。
但对于 KILL SQL,若缺少 CONNECTION_ADMIN 权限,错误信息却不同:
  1. mysql> kill 66;
  2. ERROR 1094 (HY000): Unknown thread id: 66
复制代码
此提示具有误导性,无法区分是用户未被授予 CONNECTION_ADMIN,还是目的线程受 SYSTEM_USER 保护所致,测试时这两方面都可以留意一下。
六、总结与展望

MySQL 8.0 的细粒度权限体系,特别是动态权限的引入,有效缓解了传统版本“权限过大或过小”的困境。通过单独授予 CONNECTION_ADMIN 和 PROCESS 权限,业务团队无需 SUPER 权限即可安全管理异常 SQL 线程。而 SYSTEM_USER 权限则为系统焦点线程提供了可靠保护,避免误操作导致服务中断。
dbops 默认创建 admin@'127.0.0.1'、admin@'localhost'、repl@'1%' 等账号。
欢迎讨论:是否在 dbops 1.10 新版本中支持 MySQL 8.4.x 尝鲜,默认为此三账号添加 SYSTEM_USER 权限,以进一步提拔系统安全性?
参考:
https://dev.mysql.com/doc/refman/8.0/en/grant.html
https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html

Enjoy GreatSQL
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表