ShardingSphere Show processlist & Kill 功能解读

经常使用数据库的朋友,我想你一定会有以下疑问:1. 如何查看数据库当前正在执行哪些 SQL,以及这些 SQL 处于什么状态?2. 如何终止异常的 SQL,比如一条查询大数据量表的 SELECT 语句没有携带查询条件,会拖垮整个数据库性能,这时候希望将这条异常的查询 SQL 终止掉。Apache ShardingSphere 基于这样的需求,推出了 Show processlist 和 Kill &...
摘要由CSDN通过智能技术生成

经常使用数据库的朋友,我想你一定会有以下疑问:

1. 如何查看数据库当前正在执行哪些 SQL,以及这些 SQL 处于什么状态?

2. 如何终止异常的 SQL,比如一条查询大数据量表的 SELECT 语句没有携带查询条件,会拖垮整个数据库性能,这时候希望将这条异常的查询 SQL 终止掉。

Apache ShardingSphere 基于这样的需求,推出了 Show processlist 和 Kill <processID> 这样的功能。

一、功能介绍

Show processlist:此命令能展示出 ShardingSphere 当前正在执行的 SQL 列表,以及每条 SQL 的执行进度,如果用集群模式部署 ShardingSphere,Show processlist 功能会把集群中所有 Proxy 实例正在运行的 SQL 进行汇总,然后展示出来,因此总是能够看到这一时刻正在运行的全量 SQL。

mysql> show processlist \G;
*************************** 1. row ***************************
     Id: 82a67f254959e0a0807a00f3cd695d87
   User: root
   Host: 10.200.79.156
     db: root
Command: Execute
   Time: 19
  State: Executing 0/1
   Info: update t_order set version = 456
1 row in set (0.24 sec)

Kill <processID>:此命令是基于 Show processlist 实现的功能,能够将 Show processlist 中列出的正在运行的 SQL 取消执行。

mysql> kill 82a67f254959e0a0807a00f3cd695d87;
Query OK, 0 rows affected (0.17 sec)

二、原理解析

了解了 Show processlist  和 Kill <processID> 的基本功能之后,让我们一起来探究 Show processlist 背后的原理。Kill <processID> 的原理和 Show processlist 类似,因此我们着重介绍 Show processlist 的实现原理。

2.1 SQL 是如何保存与销毁的

每一条 SQL 执行 ShardingSphere 会生成一个 ExecutionGroupContext 执行上下文对象,这个对象里会包含这条 SQL 的所有信息,其中有一个 executionID 字段来保证自己的唯一性。当 ShardingSphere 收到一条 SQL 指令(目前只对 MySQL 的 DML 和 DDL 语句做了处理,其它类型数据库会在后续版本进行支持,查询语句也被归类到了 DML 里)后,会调用 GovernanceExecuteProcessReporter#report来将 ExecutionGroupContext 信息缓存到 ConcurrentHashMap 中。

public final class GovernanceExecuteProcessReporter implements ExecuteProcessReporter {
    
    @Override
    public void report(final QueryContext queryContext, final ExecutionGroupContext<? extends SQLExecutionUnit> executionGroupContext,
                       final ExecuteProcessConstants constants, final EventBusContext eventBusContext) {
        ExecuteProcessContext executeProcessContext = new ExecuteProcessContext(queryContext.getSql(), executionGroupContext, constants);
        ShowProcessListManager.getInstance().putProcessContext(executeProcessContext.getExecutionID(), executeProcessContext);
        ShowProcessListManager.getInstance().putProcessStatement(executeProcessContext.getExecutionID(), executeProcessContext.getProcessStatements());
    }
}
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ShowProcessListManager {
    
    private static final ShowProcessListManager INSTANCE = new ShowProcessListManager();
    
    @Getter
    private final Map<String, ExecuteProcessContext> processContexts = new ConcurrentHashMap<>();
    
    @Getter
    private final Map<String, Collection<Statement>> processStatements = new ConcurrentHashMap<>();
 
    public static ShowProcessListManager getInstance() {
        return INSTANCE;
    }
    
    public void putProcessContext(final String executionId, final ExecuteProcessContext processContext) {
        processContexts.put(executionId, processContext);
    }
    
    public void putProcessStatement(final String executionId, final Collection<Statement> statements) {
        if (statements.isEmpty()) {
            return;
        }
        processStatements.put(executionId, statements);
    }
}

如上,ShowProcessListManager 类有两个缓存 Map,processContexts 和 processStatements。processContexts 里存放的是 executionID与 ExecuteProcessContext 的映射关系,

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值