时会伴随死元组产生,数据库本身可以通过 autovaccum 操作定期清理死元组(关于存
储引擎模式的说明可以参考 1.4 章节)。
2、数据库中存在大量长事务未及时提交,长事务会阻塞数据库中全局最小事务号
(OldestXmin)推进,进而导致全局最小事务号(OldestXmin)之后事务产生的死元组
无法被清理。而长事务产生的原因有如下几点:
A. 业务场景需要,如一些批量数据处理操作
B. 业务程序未遵循 ODBC 事务使用规范要求,在执行 select 语句后没有显示提交(关于
ODBC 事务使用规范可参考 1.5 章节)
C. 异常情况:如连接泄露,会话中断等。
3、数据库中死元组一直得不到清理,会导致数据表膨胀严重,进而业务程序在获取数
据时需要扫描更多的数据行才能返回结果,前端表现为业务处理积压。
Oracle 相同场景下没有出现问题的原因:
1、Oracle 的历史数据版本存储在 UNDO 表空间,事务不提交不阻塞清理历史版本数据。
2、Oracle 中要查询的历史版本数据被清理后,前端会返回 ORA-01555: snapshot too old
相关报错。
1.2.3. 原因总结
根据以上问题的分析可以看出,其共同起因是数据库中存在过多长事务或者未及时提交
的事务,进而引发数据库的内部资源争用问题,最终影响业务运行。
1.2.4. 长事务/未提交事务的隐患
长事务在任何
OLTP
数据库中均存在性能隐患,不符合
OLTP
数据库的使用规范和最佳实
践要求。主要有以下问题:
1、表空间使用增加:ASOTRE 模式下长事务会使数据的旧版本存活更长时间,因为在所有依赖
该数据的事务完成之前,数据库无法对过时的版本进行垃圾回收。这会积累撤销数据,导致撤销
日志和版本存储的空间膨胀,直至资源耗尽。USOTRE 模式下长事务会导致 Undo 表空间持续增
长,即使事务结束空间也不释放。
2、数据库性能下降:累积多个版本并管理撤销数据会增加写操作的开销。数据库必须维护和遍
历版本链,这会降低读写性能(如磐维的死元组无法清理导致表膨胀问题;Oracle 中通过 undo 数
据构造 CR 块增加资源开销)。
3、数据库并发度降低:长事务会持有锁或使版本保持活跃状态,从而阻止其他事务访问或修改
相同的数据。这会降低并发度,可能导致其他用户产生竞争和阻塞。(如某省遇到的无法建立新连
接问题,也是由于长事务过多,新连接无法获取资源锁间接导致)
文档被以下合辑收录
评论