当我delete一个表时,大约50w条数据,数据量并不大,正常执行就是2秒,但是我删的时候出现的锁死的情况,我等待了大约20秒,按了ctrl+C,这下这个表被彻底锁死了,任何操作都是没有反应。 于是我show full processlist,看到这个进程在query中,query列表还有我在表锁死后执行的其他操作。 于是我开始kill 这些线程,但当kill到delete多数据那条线程后,那个线程变成了killed,并不会消失,表依旧处于锁死状态。 准备替换表,发现在这个库里的创建表也被禁止了,或者只能死等,重启是没有用的还回回滚,因为这个事务处于回滚中。过了大概20分钟,出现了一个info为commit的线程,我把这个线程杀死了,后来意识到,其实这个应该是提交那个回滚commit的线程,555。终于,又过了半个小时,mysql自己发现了这个问题,又开始回滚,在time为1个小时小时20分钟后表终于正常了。
经过这个经历我浅显的总结了以下几点,希望有缘人指正:
1.为什么会出现两秒的sql执行了20秒还没完超出我的忍耐限度?
因为delete数据量大,没加limit或where没有命中索引,所以删要加limit会更安全。删除大量数据,会在临时数据区生成用于回滚的数据,delete操作被kill时,就会根据这些回滚数据还原。数据量越大,这个过程就越慢。但是我认为我那点数据量其实只要耐心等会就好了,错在不该暂停它。
2.show full processlist里查到的是些什么? command的遇到了Query,kill,killed 。time里是时间。info里遇到了commit。 详细的:https://blog.csdn.net/chen_jimo_c/article/details/104921212 可以用kill id来杀死,别杀commit了。time超过设置限额就记到慢查询里了。
3.killed的线程为什么kill不掉?
https://cloud.tencent.com/developer/article/1815896
它在回滚,回滚触发是按一定周期来的,重启依旧要回滚,只是会触发一下。
|