适用范围
PostgreSQL数据库
问题概述
某日,一套12.4 版本PG开发环境数据库日志中出现大量的WARNING,01000,“oldest xmin is far in the pass”告警信息。
问题原因
从log提示中可以知晓可能存在如下3个原因,导致不能及时回收旧事务:
1、存在未提交的事务。
2、存在未提交的prepared事务(二阶段事务中)。
3、存在过期的复制槽。
首先,对未提交的事务进行排查:
通过多次对pg_locks系统视图进行查询,发现transactionid列(非空)一直在发生变化,因此不存在未提交事务的情况。
其次,对prepared事务进行排查:
通过查询pg_prepared_xacts系统视图,返回数据为0行,因此也不存在prepared事务未提交的情况。
最后,对过期的复制槽进行排查:
发现PG数据库存在如下四个复制槽,且active列均为false状态:
dpagent_dfs01_back/main_slot及test_slot复制槽的restart_lsn列明显是最小的,定位至具体的wal文件:
查询wal文件属性,发现结尾为A5日志文件ctime为6月9号,结尾为39日志文件ctime为6月27号,而当前日志为8月15日:
//dpagent_dfs01_back/mainslot及test_slot复制槽存在长时间未使用的情况,为过期的复制槽。
因此从上可知晓告警触发的原因为,PG数据库中存在过期的复制槽,导致autovacuum不能及时回收旧事务。
过期的复制槽会导致如下问题:
- 使得WAL日志不能及时删除,致使WAL日志占据的磁盘空间越来越大。
- 导致autovacuum不能及时回收旧事务,引起事务回卷问题。
- warning事件引起PG alert日志文件大小迅速增长,致使alert日志占据的磁盘空间越来越大。
解决方案
- 跟业务确认复制槽使用情况,如果需要继续使用,建议立即进行修复。
- 对于已确认不再使用的的复制槽,建议及时drop掉。
- 删除复制槽的方法:select pg_drop_replication_slot(‘复制槽的名字’);