Mysql 查看事务

2018-12-18 01:10

线上割接数据,update  A表,发现非常的慢。一共才7万数据,等待响应直接connect time out了。

再次刷同样的脚本报错 Lock wait timeout exceeded; try restarting transaction。

意思就是刚才第一次跑的,把全表锁了,等第一个执行结束超时了。

执行慢的原因

如何查看事务呢,执行语句:SHOW ENGINE INNODB STATUS

中间有一段


。。。
TRANSACTIONS
------------
Trx id counter 25030860
Purge done for trx's n:o < 25030174 undo n:o < 0 state: running but idle
History list length 994
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421967015538792, not started
MySQL thread id 319518467, OS thread handle 0x7fc6dabbe700, query id 135477545 172.18.0.2 jxpx cleaning up
。。。
---TRANSACTION 25030172, ACTIVE 1651.680 sec
mysql tables in use 5, locked 5
3988 lock struct(s), heap size 357928, 77225 row lock(s), undo log entries 18852
MySQL thread id 302912855, OS thread handle 0x7fc6ef9a2700, query id 135488103 101.68.92.138 dzsb_db_c1 Sending data
select `userID` into q_user_id from t_question_node_r where question_id = new.question_id
Trx read view will not see trx with id >= 25030173, sees < 25030173


可以看到事务 TRANSACTION 25030172, ACTIVE 1651.680 sec,执行了1651秒了。看这个sql语句,才发现原来关联的表有一个触发器会执行,这个sql语句就是触发器里面的一句。原因找到了,解决办法就是先把触发器删除了,刷完脚本再把触发器加回去。。基于这个update语句 对触发器没有依赖,而且业务都停掉了不会导致触发器漏跑。

解决过程

先将触发器备份,然后drop,但是发现脚本速度没有变化,再次执行SHOW ENGINE INNODB STATUS,发现drop的语句在等待刚才的脚本。理解一下,触发器监听的是A表,A表全表锁定了,mysql的机制就是要等A表的metadata。

那就先把之前的事务给结束吧。

先找到这个事务的进程数

show processlist;

然后找到我们执行的那个语句,找到id,然后执行

kill id;
然后发现触发器已经被drop了,然后查看A表的数据,发现是刷脚本之前的状态。
然后重新执行update语句,发现一秒就刷完了。。。