Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • MySQL

    • 基础部分

      • 初识MySQL
      • 基础架构&日志
      • 事务隔离
      • 全局锁、表锁、行锁
      • 事务的隔离性和行锁
      • 索引
      • 索引深入(中)
      • 内存脏页刷盘
      • 数据库表的空间回收
      • count
      • order by
      • SQL语句性能差异分析
      • 幻读与间隙锁
      • 加锁规则案例分析
      • binlog和redolog如何写入磁盘
      • MySQL一致性与高可用性
      • kill命令
        • 被kill掉的线程发生了什么?
        • 居然kill不掉?
          • 情况一、线程没有执行到状态判断逻辑
          • 情况二、终止逻辑耗时较长
        • MySQL客户端连接问题
          • 问题一、连接状态与表的数量
          • 问题二、-quick参数
      • 全表扫描与内存占用
      • join
      • 临时表与内存表
      • 自增主键
      • insert操作加锁场景分析
      • grant
      • 分区表
      • 思维导图
    • 实战与处理方案

    • 面试

  • ORM框架

  • 数据库
  • MySQL
  • 基础部分
phan
2023-07-05
目录

kill命令

# kill命令

kill query id:表示中止当前线程id正在执行的语句。

kill (connection) id:表示杀掉并断开该线程的连接。

当前查询语句执行慢,或是存在锁等待,都可以直接kill。

# 被kill掉的线程发生了什么?

A线程执行kill query thread_B命令关闭B线程的查询操作后,MySQL里处理kill命令的线程做了两件事:

  • 将B线程的线程状态设置为THD::KILL_QUERY
  • 给B线程发送一个信号

B线程执行查询语句的过程中,在“埋点”处判断线程状态,如果发现状态处于THD::KILL_QUERY,才开始进入语句终止逻辑。

# 居然kill不掉?

# 情况一、线程没有执行到状态判断逻辑

假定当前并发查询线程数为2,线程C执行查询语句时当前并发线程数已达阈值,因此被阻塞。

然而线程D关闭当前C线程的查询操作时,线程C并没有反应。等到线程E直接断开线程C的连接时才有反应。

线程C在被阻塞的情况下,它的等待逻辑是每隔10毫秒轮询判断是否可以进入InnoDB执行,如果不行则进入sleep状态。虽然线程D已经修改了C的状态同时发送了i信号,但是在整个轮询进入InnoDB的过程中,C并没有进入埋点判断状态,也就不会执行终止逻辑。

而对于线程E来说,关闭连接主要做了两件事:

  • 讲C线程的状态设置为THD::KILL_CONNECTION
  • 关闭C线程的网络连接

关闭网络连接之后线程C马上收到了提示。show processlist可以发现kill掉的线程依然存在(killed),只有等到线程C进入InnoDB执行查询条件前,判断当前状态已经被kill掉后才会真正进入终止逻辑。

# 情况二、终止逻辑耗时较长

终止逻辑执行时间较长,只有等到完整的执行完后,才算是真正结束。常见有以下场景:

  • 大事务执行期间被kill掉。此时整个终止逻辑中,还包括对整个大事务的回滚操作,非常耗时。
  • 大查询回滚。整个终止逻辑中,需要删除查询过程中产生的临时文件,文件大可能就需要等待IO资源,导致耗时增加。
  • DDL命令执行到最后阶段,忽然被kill掉,终止逻辑中处理临时文件的耗时也会比较大。

总结:对于情况一可以手动提高并发线程数,让被kill掉的线程更快执行终止逻辑。而情二可以减少系统IO压力让它加速。

# MySQL客户端连接问题

# 问题一、连接状态与表的数量

问题1

客户端连接时,如果库中的表数量比较多的情况下,会发现连接数据库时比较慢。

客户端进行数据库连接时,会做以下几个步骤:

  1. 客户端与MySQL服务端进行TCP握手,用户校验,获取权限。
  2. 连接成功后,MySQL客户端会提供一个TAB快捷键自动补全库名和表名的功能。而要实现这个功能,客户端还要进行以下操作:
    • 执行show databases;获取库名
    • 执行show tables;获取表名
    • 把上述两个结果用于在本地构建一个哈希表

显然客户端连接时,感知到的慢正是因为构建哈希表才比较慢。客户端在连接时,可以添加-A来关闭这个自动补全功能。

# 问题二、-quick参数

问题2

客户端连接时,指定-quick参数并不会加速服务端,反而会影响服务端性能。

MySQL客户端发送请求后,接收服务端返回结果的方式有两种:

  • 本地开一片内存,将服务端结果保存起来。

  • 不缓存,本地(客户端)处理完一个返回结果后,再接收读取另一个结果。

MySQL默认采用第一种缓存的方式。在客户端连接命令加上-quick后,那么就会使用上面第二种不缓存的方法。如果采用不缓存的方法影响如下:

  • 对于服务端来说,如果客户端本地没有处理完,那么当前服务端的发送结果就会被阻塞,从而导致服务端变慢
  • 对于客户端而言,①可以减少本地内存占用 ②跳过表名自动补全 ③❓不会把执行命令记录到本地的命令历史文件

总结:-quick参数有利于客户端,而不利于服务端。

编辑 (opens new window)
#数据库
上次更新: 2023/12/15, 15:49:57
MySQL一致性与高可用性
全表扫描与内存占用

← MySQL一致性与高可用性 全表扫描与内存占用→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式