一、问题描述
今天上线,生产mysql有个2700万数据的大表lt_integral_detail_info
,准备给这个表加字段、加索引;
执行加字段加索引的命令比较费时,结果这时有人对这个表执行了多个select count(*)
操作,导致直接把Navicat会话挤掉了,CPU也飙上去了,其它的对这个数据库的增删改查也变的很慢,半天跑不出来。
赶紧联系数据库管理人员,把加字段、加索引的操作kill掉了,把卡死的select count(*)
操作也标记kill了,但是半天没有kill掉。
如图:
可以看到卡了挺长时间了,也没有kill掉。
此时,如果对其它表进行操作,是没有问题的;但是如果再操作lt_integral_detail_info表,就又会卡死,其它的对这个数据库的增删改查也变的很慢。
二、网上的解决方法
1.网上发现了这样的一个文章:
https://cloud.tencent.com/developer/article/1857161?from=15425&areaSource=102001.9&traceId=OjyLyWs7caMy1jo-2hFIA
大概意思是,mysql执行kill操作时,是先打个标记,后续再真正kill;
mysql低版本有bug,是基于主键并行读操作造成的;
触发了这个bug,就会kill不掉sql语句。
2.解决方法,网上说,可以升级mysql到8.0.22
3.如果不能升级,就可以增加配置:
innodb_parallel_read_threads=1
然后重启MySQL解决。
三、个人的解决方法
1.正常情况下,kill一个sql语句是很快就会生效的;标记为kill几个小时都没有kill掉的情况很少见;
可以选择继续等待,看能否正常kill。(如上图,卡住了7个sql,2-3小时后发现少了一个,说明2-3个小时后还是可以正常kill掉一个的。)
2.由于生产环境不能轻易重启mysql,因此就临时建了另一个表,从备库把数据同步了过去,卡住的表就先放着不动了。(得尽快发完版,还不能影响正常业务)
三、总结
1.对大表执行增加字段、增加索引的sql语句时,就尽量不要再操作这张表了,防止sql卡死并且kill不掉。
2.如果有sql语句操作某张表、标记为kill后还是杀不掉,就尽量不要再操作这个表了,否则新的操作sql还会卡死、并且将导致对库中其它表的操作也变的很慢。(只能再标记为kill)
3.标记完kill后杀不掉,可以多等待一段时间(几个小时、一整晚),看看有没有什么变化,有可能可以自己恢复,慢慢就kill掉了。
4.如果允许,就把mysql升级到8.0.22
5.或者增加配置innodb_parallel_read_threads=1
,然后重启mysql解决。