mysql“空事务”引发的锁阻塞

日常运维中,innodb_trx视图中经常会出现running时间很长的事务,但是并没有显示sql语句,很多DBA对这类问题很困惑。
mysql“空事务”引发的锁阻塞-1
比如上图中,show processlist 查看到ID对应的session一直存在,status状态时而running时而 sleep,最后分析发现,应用程序使用 begin、start transction 启动了一个大事务,不停的轮询更新数据,大事务运行时间超过 1 天。

如何追踪定位?

一般情况下,应用程序通过begin执行显示事务后,事务中的sql已经执行,但是该显示事务一直没有提交时就会出现这种现象。下面sql语句会查询到“空事务”中执行的上一条sql语句,拿到sql后找开发一起排查sql来源,最后尝试复现找到根因。

select trx_id,trx_operation_state,trx_mysql_thread_id prs_id,now(), trx_started,to_seconds(now())-to_seconds(trx_started) trx_es_time, user,db,host,command,state,Time,info current_sql,PROCESSLIST_INFO last_sql,t4.ROWS_AFFECTED 'ROWS_AFFECTED(last)',t4.ROWS_SENT as 'ROWS_SENT(last)' ,t4.ROWS_EXAMINED as 'ROWS_EXAMINED(last)',t1.trx_rows_locked,t1.trx_rows_modified from information_schema.innodb_trx t1,information_schema.processlist t2,performance_schema.threads t3,performance_schema.events_statements_current t4 where t1.trx_mysql_thread_id=t2.id and t1.trx_mysql_thread_id=t3.PROCESSLIST_ID and t1.trx_mysql_thread_id!=connection_id() and t3.THREAD_ID = t4.THREAD_ID and to_seconds(now())-to_seconds(trx_started) >= 5;