MySQL实战45讲
林晓斌
网名丁奇,前阿里资深技术专家
立即订阅
43178 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 这一次,让我们一起来搞懂MySQL
免费
基础篇 (8讲)
01 | 基础架构:一条SQL查询语句是如何执行的?
02 | 日志系统:一条SQL更新语句是如何执行的?
03 | 事务隔离:为什么你改了我还看不见?
04 | 深入浅出索引(上)
05 | 深入浅出索引(下)
06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
07 | 行锁功过:怎么减少行锁对性能的影响?
08 | 事务到底是隔离的还是不隔离的?
实践篇 (37讲)
09 | 普通索引和唯一索引,应该怎么选择?
10 | MySQL为什么有时候会选错索引?
11 | 怎么给字符串字段加索引?
12 | 为什么我的MySQL会“抖”一下?
13 | 为什么表数据删掉一半,表文件大小不变?
14 | count(*)这么慢,我该怎么办?
15 | 答疑文章(一):日志和索引相关问题
16 | “order by”是怎么工作的?
17 | 如何正确地显示随机消息?
18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?
19 | 为什么我只查一行的语句,也执行这么慢?
20 | 幻读是什么,幻读有什么问题?
21 | 为什么我只改一行的语句,锁这么多?
22 | MySQL有哪些“饮鸩止渴”提高性能的方法?
23 | MySQL是怎么保证数据不丢的?
24 | MySQL是怎么保证主备一致的?
25 | MySQL是怎么保证高可用的?
26 | 备库为什么会延迟好几个小时?
27 | 主库出问题了,从库怎么办?
28 | 读写分离有哪些坑?
29 | 如何判断一个数据库是不是出问题了?
30 | 答疑文章(二):用动态的观点看加锁
31 | 误删数据后除了跑路,还能怎么办?
32 | 为什么还有kill不掉的语句?
33 | 我查这么多数据,会不会把数据库内存打爆?
34 | 到底可不可以使用join?
35 | join语句怎么优化?
36 | 为什么临时表可以重名?
37 | 什么时候会使用内部临时表?
38 | 都说InnoDB好,那还要不要使用Memory引擎?
39 | 自增主键为什么不是连续的?
40 | insert语句的锁为什么这么多?
41 | 怎么最快地复制一张表?
42 | grant之后要跟着flush privileges吗?
43 | 要不要使用分区表?
44 | 答疑文章(三):说一说这些好问题
45 | 自增id用完怎么办?
特别放送 (1讲)
直播回顾 | 林晓斌:我的 MySQL 心路历程
结束语 (1讲)
结束语 | 点线网面,一起构建MySQL知识网络
MySQL实战45讲
登录|注册

32 | 为什么还有kill不掉的语句?

林晓斌 2019-01-25
在 MySQL 中有两个 kill 命令:一个是 kill query + 线程 id,表示终止这个线程中正在执行的语句;一个是 kill connection + 线程 id,这里 connection 可缺省,表示断开这个线程的连接,当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的。
不知道你在使用 MySQL 的时候,有没有遇到过这样的现象:使用了 kill 命令,却没能断开这个连接。再执行 show processlist 命令,看到这条语句的 Command 列显示的是 Killed。
你一定会奇怪,显示为 Killed 是什么意思,不是应该直接在 show processlist 的结果里看不到这个线程了吗?
今天,我们就来讨论一下这个问题。
其实大多数情况下,kill query/connection 命令是有效的。比如,执行一个查询的过程中,发现执行时间太久,要放弃继续查询,这时我们就可以用 kill query 命令,终止这条查询语句。
还有一种情况是,语句处于锁等待的时候,直接使用 kill 命令也是有效的。我们一起来看下这个例子:
图 1 kill query 成功的例子
可以看到,session C 执行 kill query 以后,session B 几乎同时就提示了语句被中断。这,就是我们预期的结果。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《MySQL实战45讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(34)

  • Leon📷 置顶
    kill connection本质上只是把客户端的sql连接断开,后面的执行流程还是要走kill query的,是这样理解吧

    作者回复: 这个理解非常到位👍

    额外的一个不同就是show processlist的时候,kill connection会显示“killed”

    这两句加起来可以用来替换我们文中的描述👍

    2019-01-30
    12
  • Mr.sylar
    老师,我想问下这些原理的"渔"的方法除了看源码,还有别的建议吗

    作者回复: 不同的知识点不太一样哈,
    有些可以看文档;
    有些可以自己验证;
    还有就是看其他人文章,加验证;(就是我们这个专栏的方法^_^)

    2019-01-25
    5
  • wjz1991
    老师,之前也是有遇到程序问题导致cpu爆满,临时先把innodb_thread_concurrency设置为16(降低cpu避免影响同机器实例),然后不断去kill,后面程序人员修复了这个问题后,一堆的killed的语句不释放,设置innodb_thread_concurrency=0,等了半个月都没释放,后面还是安排主从切换,强制重启解决,请问老师,这是为什么?

    作者回复: 如果是因为这个原因的,应该是设置innodb_thread_concurrency=0就会退出的。。
    你这个情况可能卡在别的地方了,下次如果再出现,要重启之前,用pstack保留个现场哦

    2019-02-13
    4
  • 夹心面包
    对于结尾的问题,我觉得肯定是等待,即便是mysql重启,也是需要对未提交的事务进行回滚操作的,保证数据库的一致性
    2019-01-25
    4
  • HuaMax
    课后题。我认为需要看当时的业务场景。重启会导致其他的连接也断开,返回给其他业务连接丢失的错误。如果有很多事务在等待该事务的锁,则应该重启,让其他事务快速重试获取锁。另外如果是RR的事务隔离级别,长事务会因为数据可见性的问题,对于多版本的数据需要找到正确的版本,对读性能是不是也会有影响,这时候重启也更好。个人理解,请老师指正。

    作者回复: 有考虑到对其他线程的影响,这个👍

    其实这种时候往往是要先考虑切换(当然重启也是切换的)
    如果只看恢复时间的话,等待会更快

    2019-01-26
    2
  • 似水流年
    老师,请问我直接在操作系统层面用kill命令掉会话的进程,这个会话的事物应该会回滚,除此外有不良影响吗?

    作者回复: 就是回滚的影响,没有其他的了

    2019-03-13
    1
    1
  • Lukia
    请教老师,删除中间列和修改末尾列这两种DDL的差别在什么地方呢?

    作者回复: 对,其实只有 改索引、 加最后一列、删最后一列
    其他的大多数不行,比如删除中间一列这种

    作者回复: 删除中间列,就没办法用切换的那个方案。
    MySQL的备库比主库多一个字段或少一个字段,这时候日志还是可以应用成功的(但如果少的是中间一个字段,字段就会对应错了)

    2019-02-19
    1
  • think_wtw
    老师如果正在执行ddl 比如删除一列或者创建一个索引,执行kill query也是事物进行回滚的是吗?内部会做什么操作? 来得晚还没追上课程。谢谢解答!

    作者回复: 对,进行回滚

    取决于做到什么程度了,总之效果就是中间生成的数据全部清理掉,恢复到未执行ddl之前的状态

    2019-02-13
    1
  • 斜面镜子 Bill
    “采用不缓存的方式时,如果本地处理得慢,就会导致服务端发送结果被阻塞,因此会让服务端变慢” 这个怎么理解?

    作者回复: 堵住了不就变慢了😆

    2019-01-28
    1
  • 700
    老师,您好。客户端版本如下:
    mysql Ver 14.14 Distrib 5.7.24, for linux-glibc2.12 (x86_64) using EditLine wrapper

    老师,再请教另一个问题。并非所有的 DDL 操作都可以通过主从切换来实现吧?不适用的场景有哪些呢?

    作者回复: 对,其实只有 改索引、 加最后一列、删最后一列
    其他的大多数不行,比如删除中间一列这种

    2019-01-27
    1
  • 千年孤独
    可能不是本章讨论的问题,我想请问老师“MySQL使用自增ID和UUID作为主键的优劣”,基于什么样的业务场景用哪种好?

    作者回复: 后面会有文章会提到这个问题哈:)

    2019-01-27
    1
  • Geek_a67865
    也遇到@发条橙子一样的问题,例如队列两个消息同时查询库存,发现都不存在,然后就都执行插入语句,一条成功,一条报唯一索引异常,这样程序日志会一直显示一个唯一索引报错,然后重试执行更新,我暂时是强制查主库

    作者回复: “我暂时是强制查主库” 从这就看你是因为读是读的备库,才出现这个问题的是吧。

    发条橙子的问题是,他都是操作主库。

    其实如果索引有唯一键,就直接上insert。
    然后碰到违反唯一键约束就报错,这个应该就是唯一键约束正常的用法吧😆

    2019-01-26
    1
  • gaohueric
    老师您好,一个表中 1个主键,2个唯一索引,1个普通索引 4个普通字段,当插入一条全部字段不为空的数据时,此时假设有4个索引文件,分别对应 主键 唯一性索引,普通索引,假设内存中没有这个数据页,那么server是直接调用innodb的接口,然后依次校验 (读取磁盘数据,验证唯一性)主键,唯一性索引,然后确认无误A时刻之后,吧主键和唯一性索引的写入内存,再把普通索引写入change buffer?那普通数据呢,是不是跟着主键一块写入内存了?

    作者回复: 1. 是的,如果普通索引上的数据页这时候没有在内存中,就会使用change buffer
    2. “那普通数据呢,是不是跟着主键一块写入内存了?” 你说的是无索引的字段是吧,这些数据就在主键索引上,其实改的就是主键索引。

    2019-01-26
    1
  • 700
    老师,请教。
    1)文中开头说“当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的”。我个人在平时使用中就是按默认的执行,不管这个线程有无正在执行语句。不知这样会有什么潜在问题?
    2)文中说“实际上,执行 Ctrl+C 的时候,是 MySQL 客户端另外启动一个连接,然后发送一个 kill query 命令“。这个怎么解释呢?
    我开启 general log 的时候执行 Ctrl+C 或 Ctrl+D 并没有看到有另外启动一个连接,也没有看到 kill query 命令。general log 中仅看到对应线程 id 和 Quit。
    3)MySQL 为什么要同时存在 kill query 和 kill connection,既然 kill query 有无效的场景,干嘛不直接存在一个 kill connection 命令就好了?那它俩分别对应的适用场景是什么,什么时候考虑 kill query,什么时候考虑 kill connection?我个人觉得连接如果直接被 kill 掉大不了再重连一次好了。也没啥损失。
    4)小小一个总结,不知对否?
    kill query - 会出现无法 kill 掉的情况,只能再次执行 kill connection。
    kill connection - 会出现 Command 列显示成 Killed 的情况。

    作者回复: 1. 一般你执行kill就是要停止正在执行的语句,所以问题不大😋
    2. 不应该呀, KILL QUERY 是大写哦,你再grep一下日志;
    3. 多提供一种方法嘛。kill query是指你只是想停止这个语句,但是事务不会回滚。一般kill query是发生在客户端执行ctrl+c的时候啦。平时紧急处理确实直接用kill + thread_id。 好问题
    4. 对,另外,在kill query无效的时候,其实kill connection也是无效的

    2019-01-25
    1
  • Justin
    想咨询一个问题 如果走索引找寻比如age=11的人的时候是只会锁age=10到age=12吗 如果那个索引页包含了从5到13的数据 是只会锁离11最近的还是说二分查找时候每一个访问到的都会锁呢

    作者回复: 只会锁左右。

    2019-01-25
    1
  • AI杜嘉嘉
    我想请问下老师,一个事务执行很长时间,我去kill。那么,执行这个事务过程中的数据会不会回滚?

    作者回复: 这个事务执行过程中新生成的数据吗? 会回滚的

    2019-01-25
    1
  • Dkey
    老师,请教一个 第八章 的问题。关于可见性判断,文中都是说事务id大于高水位都不可见。如果等于是不是也不可见。还有一个,readview中是否不包含当前事务id。谢谢老师

    作者回复: 代码实现上,事务生成trxid后,trxid的分配器会+1,以这个加1以后的数作为高水位,所以“等于”是不算的。

    其实有没有包含是一样的,实现上没有包含。

    2019-01-25
    1
  • Ryoma
    想得简单点:既然事务处于回滚状态了,重启MySQL这部分事务还是需要回滚。私以为让它执行完成比较好。
    2019-01-25
    1
  • Jayden 王凯豪
    create table select distinct from t1 join t2 join t3... 十个关联表超大事务,跑了一整晚,第二天早上强制kill都kill不掉,最后只能直接重启OS
    2019-11-20
  • 晓蓝
    我现在就遇到这个问题了,session状态是killed state 是sending date, 是select 一个大表,如果不重启,现在有啥方法释放么,pstak部分信息如下:
    留意不能贴,留意太长。。
    2019-09-21
    2
收起评论
34
返回
顶部