Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL定位长事务

MySQL定位长事务(Identify Long Transactions)的实现

作者:V1ncent Chen

在MySQL的运行中,经常会遇到一些长事务,本文主要介绍了MySQL定位长事务,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在MySQL的运行中,经常会遇到一些长事务。长事务意味着长时间持有系统资源,这在OLAP系统中很常见,但在OLTP系统中,长事务意味着争用、并发降低,等待。长事务伴随的典型现象就是经常听到开发人员说"xxx表被锁住了…"

一、长事务的成因

长事务表面上来看都是运行时间过长。但其背地里的成因却可能不同,我认为长事务的成因可以分为以下3类:

第一类:表、索引设计不合理,这种就是常见的慢SQL导致事务执行时间过长,有些慢SQL在数据量低的时候可能无法发现,当生产数据逐渐增多,慢SQL的问题会越来越严重,最终导致长事务。这类长事务的解决方式是优化SQL(可以通过慢查询日志抓取慢SQL)。

第二类:事务设计不合理是将大量的逻辑处理塞到一个事务中,导致事务过于臃肿。这种问题需要从业务层面分析,看是否可以将过大事务拆分成多个独立事务,降低耦合,对于OLTP系统,大部分都应该是短小的事务。

第三类:事务未正常结束,这种可能是忘记提交,或者事务处理中出错,但用户没有后续处理。当事务某条语句出错时,其仍然处于活跃状态,已成功执行语句的锁会继续持有。某些人可能会直接杀死客户端连接,但对数据库来说,并没有收到显式结束事务的命令,它保持事务是活跃状态,一直等待用户的命令,直到互动超时(interactive_timeout 默认28800秒,即会话8小时没活动,关闭会话)。

以上三类长事务中,第一二类属于性能优化问题,事务通常可以正常结束。危害最大的是第三类,这种被遗忘的事务会长时间占用系统资源(默认8小时),是不可接受的。在事务执行出现问题时,需要显式的rollback或commit来结束该事务,如果客户端已经杀死连接,无法控制事务,那么只能从服务端杀死该会话。

二、查找长事务

MySQL已提供了相关性能视图帮助我们查询活跃事务信息,通过performance_schema.events_transactions_current可以查询所有当前事务的event,配合其他视图即可定位长事务及其会话信息,主要用到的视图如下:

各个视图的关键字段,即要查询的关键信息解释如下:

performance_schema.events_transactions_current

注:如果是MySQL8.0.16之后的版本,可以直接用format_pico_time()函数将timer_wait转换成易读的格式。

performance_schema.threads

sys.processlist

了解了上面3个视图提供的信息含义,我们可以很容易的找出当前哪些事务执行时间过长,及这些事务当前在做什么:

select
t.thread_id 线程ID,
t.processlist_id 会话ID,
t.processlist_user 用户,
t.processlist_host 用户地址,
t.processlist_db 数据库,
p.command 会话状态,
e.state 事务状态,
format_pico_time(e.timer_wait) 事务持续时长,
p.current_statement 执行SQL
from performance_schema.events_transactions_current e
join performance_schema.threads t on t.thread_id=e.thread_id
left join sys.processlist p on p.thd_id=t.thread_id
where t.type='FOREGROUND'
and e.state='ACTIVE'
order by e.timer_wait desc;

定位到长事务后,分析长事务属于哪一类,决定是否需要优化事务或人工介入。例如上面第二个事务,如果判断会话异常,可以通过杀死会话ID来结束该会话(事务);

kill 451;

到此这篇关于MySQL定位长事务(Identify Long Transactions)的文章就介绍到这了,更多相关MySQL定位长事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文