【MySQL】长事务

2021年11月21日 阅读数:9
这篇文章主要向大家介绍【MySQL】长事务,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
一. 长事务缘由

1. set autocommit=0

  1. 这个命令会关闭当前线程的事务自动提交功能
  1. 意味着若是只执行一个 select 语句,这个事务就启动了,而且不会自动提交。
    这个事务持续存在直到主动执行 commit 或 rollback 语句,或者断开链接。若是是长链接,就致使了长事务。
  1. 有些客户端链接框架会默认链接成功后先执行一个 set autocommit=0 的命令。这就致使接下来的查询都在事务中,若是是长链接,就致使了长事务。
  1. 因此建议使用【set autocommit=1】, 经过显式语句的方式来启动事务。

2. 事务方法业务复杂,执行时间长


二. 长事务危害

1. 占用大量的存储空间

  1. 在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操做。记录更新前的值,经过回滚操做,就能够获得前一个状态的值。
  2. 这些记录下来的回滚操做就是回滚段,长事务意味着系统里面会存在很老的回滚段。因为这些事务随时可能访问数据库里面的任何数据,因此这个事务提交以前,这些回滚记录数据都必须保留,这就会致使占用大量的存储空间。

【MySQL】长事务_MySQL


2. 占用锁资源,甚至拖垮整个库

  1. 事务内的增删改操做都会对数据加锁,在事务提交或回滚前会一直占用锁资源

三. 查看长事务
  1. 查找持续时间超过 60s 的事务
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

四. 解决长事务

1. 程序端

  1. 确认是否使用了【set autocommit=0】,建议使用【set autocommit=1】。
  2. 确认是否有没必要要的只读事务。
  3. 经过 SET MAX_EXECUTION_TIME 命令,来控制每一个语句执行的最长时间,避免单个语句执行太长时间。
  4. 经过【消息队列、异步线程】分离事务方法内的业务,减小事务方法的执行时间。

2. 数据库端

  1. 监控 information_schema.Innodb_trx 表,设置长事务阈值,超过就报警 或者 kill。
  2. 若是使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 设置成 2(或更大的值)。若是真的出现大事务致使回滚段过大,这样设置后清理起来更方便。
  3. 在业务功能测试阶段要求输出全部的 general_log,分析日志行为提早发现问题。