为什么建议你尽量不要使用长事务?
1.长事务意味着系统里会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录(MVCC机制)必须保留,这就会导致大量占用存储空间。
2.MySQL5.5及以前的版本,回滚日志是跟数据字典一起放在ibdata文件里面的,即使长事务最终提交,回滚段被清理,文件也不会变小。
3.长事务还会占用锁资源。
系统中应当避免长事务,会用什么方案来避免出现或者处理?
应用开发端来看:
- 是否使用自动提交事务,可以打开general_log(mysql中的所有操作将会记录下来),随便跑一个业务来确认。
- 确认是否有不必要的只读事务。有些框架习惯不管什么语句先用begin/commit框起来。我见过有些业务并没有这个需要,但是也把好几个select语句放到事务中。
- 通过set max_execution_time命令来控制每个语句的最长执行时间。
数据库端来看:
- 监控Innodb.trx表,设置长事务阈值,超过就报警/或者kill。
使用方式:/*使用information_schema库的innodb_trx这个表中查询长事务,比如下面这个语句,用于查询持续时间超过60s的事务。*/ select * from information_schema.innodb_trx where >TIME_TO_SEC(timediff(now(),trx_started))>60
- Percona的pt-kill这个工具不错,推荐使用。(用来杀掉指定匹配条件的慢查询会话以保证mysql实例的可用性。)
- 在业务功能测试阶段要求输出所有的 general_log,分析日志行为提前发现问题。
- 如果使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 设置成 2(或更大的值)。如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便。
网友评论