1、长事务的定义
在给出长事务的定义之前,需要解释一下数据库的事务这个概念,数据库的事务是指一种机制或是一个操作序列,它包含了一组数据库sql,因此事务是指客户端提交到数据库服务端的一个不可分割的最小单元。简单来说,长事务就是指那些运行时间比较长且操作数据比较多的事务。
2、长事务发生的原因
(1) 开启事务未提交
a. 自动提交参数autocommit关闭了,每次执行完sql都需要主动执行commit或rollback,不然会一直持续存在,造成长事务;
使用begin或 start transaction 显示开启事务,但是执行完事务sql未主动执行commit或rollback
(2) 事务执行时间长
a. sql数量过多,可能为批量sql放在一个事务中执行,执行时间较久;
b. sql执行较慢,事务中存在慢sql,影响了整个事务的执行效率。
3、长事务的危害
(1) 锁定数据过多过久,容易造成大量的锁超时
AntDB-M默认存储引擎是InnoDB,修改数据会产生行锁,如果此时该事务没有提交,就会一直持有锁资源,造成其他涉及改行修改的事务进入等待状态,严重时会造成连接线程暴增、cpu资源耗尽,数据库夯住的情况,对业务的危害极大。
(2) 回滚记录占用大量存储空间,事务回滚时间长
在事务进行中为了保证事务的一致性,每条记录更新的时候也都会同时记录一条回滚操作。通过回滚操作记录上的新值能够恢复到修改前的数据,这样保证一条事务提交失败后,能够恢复到之前的状态,数据始终能够保持一致。
对于同一个数据,在回滚日志中会存在不同的版本数据,将不同版本数据的读取操作分为快照读和当前读,快照读为一个事务中始终只读取开启时数据的最新版本,不因数据的修改而改变;而当前读是指一个事务中每次读取都会取当前最新的版本数据,由此实现了事务的隔离性。
回滚日志保证了事务的一致性和隔离性,当系统判断回滚日志没有事务需要用到时就会进行删除。而长事务会导致系统中存在很老的事务视图,该事务之后的回滚日志都要保存,因此占用大量的无用内存,而且一旦事务回滚,也会逐条按照回滚日志的顺序执行,这个过程耗时很久。
(3) 长事务会造成主从延迟
因为主库上必须等待事务执行完成才会写入binlog,再传给备库,所以在一个主库上执行的事务过长,也可能会导致从库延迟。特别是在AntDB-M的MGR高可用集群里,长事务会导致事务提交失败,出现大量回滚,还可能因为大的延时,导致节点退出集群。
4、长事务的捕捉
对长事务的捕捉要先明确执行时间多久的事务认定为长事务,这里可以根据实际业务要求以及监控指标确定。这里假设超过十秒的就判定为长事务,执行以下sql进行查看:
select now(),(UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(a.trx_started)) diff_sec,b.id,b.user,b.host,b.db,d.SQL_TEXT from information_schema.innodb_trx a inner join information_schema.PROCESSLIST b on a.TRX_MYSQL_THREAD_ID=b.id and b.command = 'Sleep' inner join performance_schema.threads c ON b.id = c.PROCESSLIST_ID inner join performance_schema.events_statements_current d ON d.THREAD_ID = c.THREAD_ID where diff_sec > 10;
5、长事务的处理
(1) 客户端
a. 确认是否使用了set autocommit=0,建议使用set autocommit=1开启事务自动提交
b. 事务开始到结束的时间内,避免做耗时的操作,比如网络请求等
c. 通过 SET MAX_EXECUTION_TIME 命令,来控制每个语句执行的最长时间,避免单个语句执行太长时间
d. 对事务中的慢sql进行性能优化
(2) 服务端
a. 使用脚本监控information_schema.Innodb_trx 表,设置长事务阈值,超过就报警或直接kill
b. innodb_undo_tablespaces 参数设置成2(或更大的值),如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便
c. 开启slow log设置,定期优化慢sql
关于亚信安慧AntDB数据库
AntDB数据库始于2008年,在运营商的核心系统上,服务国内24个省市自治区的数亿用户,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行超十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。