前言
kill过程并不是直接终止,如果线程处于锁等待的过程,那么并不能感知到kil命令。只有等到获取锁之后才能发现进入了kill。
为什么还有kill不掉的sql语句
kill的执行流程
在语句的执行过程中,有多个埋点位置,用来判断是否进行了kill命令。
导致kill命令生效慢的原因
如果io过大,或者事务回滚过慢,也会导致kill之后响应很慢。
- 超大事务执行期间被kill。这时候,回滚操作需要对事务执行期间生成的所有新数据版本做回收操作,耗时很长。
- 大查询回滚。如果查询过程中生成了比较大的临时文件,加上此时文件系统压力大,删除临时文件可能需要等待IO资源,导致耗时较长。
- DDL命令执行到最后阶段,如果被kill,需要删除中间过程的临时文件,也可能受IO资源影响耗时较久。
对客户端的两个误解
表越多连接越慢
除此之外有时候连接mysql时,由于表过多发现连接很慢。其实连接过程只是tcp握手,权限校验。导致很慢的原因是因为客户端需要构建一个库名,表名自动补全的功能。就比如我们在客户端数据一个表的前缀就自动帮我们找到相关的表。
mysql连接之后客户端构建自动补全功能的流程:
- show database
- 切到db1,show tables
- 两个命令的结果用来构建一个哈希表。
哈希表构建的过程比较慢导致的。
我们感知到的连接过程慢,其实并不是连接慢,也不是服务端慢,而是客户端慢。
可以通过在连接的时候加一个 -A的参数来关闭这个功能
quick命令可以加快
还有一个 -quick的命令也可以关闭,但是它可能会导致运行更慢
为什么叫quick反而更慢了呢。
因为quick
对返回的结果不是缓存存起来,而是直接展示,如果客户端处理较慢,那么就会阻塞服务端。
那么为什么叫quick,因为如果使用缓存对于大量的数据的话,会占用客户端的io导致客户端运行较慢,所以它quick的是客户端的速度。
报告学习完一篇文章《误删数据后,除了跑路还能做什么》
误删行,可以通过一个工具,读取binlog的日志,然后把删除命令改为insert重放就可以
误删表和库,可以通过定期备份库表,然后误删之后,通过最近的备份恢复,然后再通过binlog的日志从备份起开始执行binlog然后恢复。
创建延迟库,一般主库上误删命令很快会到从库执行导致问题,那么可以通过一个延迟库,比如延迟执行主库的binlog一个小时,那么发现问题后,即使通过延迟库恢复到一个小时之前的状态,然后再通过binlog恢复这一个小时的数据。
rm删除是最简单的,删除一个库之后,系统自动切从库执行了,只需要再这台机器上重新恢复再切回来即可