MySQL的长事务会因为事务视图太老,MVCC时中需要执行很多的回滚操作才能得到对应的数据版本,而且还会形成很大的回滚段,所以会影响性能。 那么在项目开发中,应该如何避免大事务呢?
一般可以从客户端和服务器端分别进行控制
客户端
- 设定事务执行的超时时间(SET MAX_EXECUTION_TIME),可以避免意外的长事务占用过多资源
- 事务开始到结束的时间内,避免做耗时的操作,比如网络请求等
- 尽量把容易有冲突的SQL语句写在业务逻辑后面,减少锁占用时间
服务器端
- 监控 information_schema.Innodb_trx 表,设置长事务阈值,超过就报警或者 kill
- 删除超时的连接:
pt-kill --busy-time 60 --kill
- 在业务功能测试阶段要求输出所有的 general_log,分析日志行为提前发现问题。日志分析可以使用
pt-query-digest
- 如果使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 设置成 2(或更大的值)。如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便。但是这个选项在MySQL未来的版本会去掉,到时候回滚段会使用改进后的存储方式,比如支持压缩
The innodb_undo_tablespaces option is deprecated; expect it to be removed in a future release.
网友评论