起因:下午同事在修改表结构时,发现修改语句被阻塞无法执行。
查询后发现有几个事务已经执行了几个小时,一直没有提交,修改表结构的操作必须等待所有已经开启的事务提交后才能执行。
查看事务
select * from information_schema.INNODB_TRX\G;
查看线程
SELECT * FROM information_schema.processlist;
只能找到这个未提交的事务的事务id和线程id,但都处于sleep状态,不好分析事务内容到底是什么,但是通过processList 里的IP定位到了对应的服务器和执行的脚本。
当时先杀死了这些线程。
重新运行脚本重现了当时的问题。
查看锁等待
SELECT * FROM information_schema.innodb_lock_waits;
查看还未结束的执行sql
select * from performance_schema.events_statements_current\G;
通过这个方法找到了执行的查询语句。
MySQL 的 SELECT,INSERT,UPDATE或DELETE都会开启事务。
如果AUTOCOMMIT设置为1(默认值),每一个SQL语句都被认为是一个完整的事务。 AUTOCOMMIT设置为0时,在随后的一系列语句的作用就像一个事务,直到一个明确的COMMIT语句结束。
脚本是python 写的,用的pymysql 操作数据库。pymysql 初始化连接时,默认 autocommit=False, 代码里也没有手动commit, 脚本本身是常驻进程,所以查询事务一直没有提交。
将pymysql 的连接初始化的 autocommit 设为 True, 至此问题解决。
参考链接:
http://www.ywnds.com/?p=8841
http://blog.csdn.net/zyz511919766/article/details/49335729