问题修复记录:DMS 任务失败导致 PostgreSQL 磁盘占用异常


起因是一个 AWS PostgreSQL 数据库提示磁盘空间不足,查询数据库的磁盘占用发现总数据量不超过 100 GB,但从面板看磁盘消耗了 2 TB 多。且可用磁盘空间每天少 30 多 GB。

查了一圈儿,最终定位到是 Slot 占用了非常大的空间

SQL 语句

-- PostgreSQL v9
SELECT slot_name, pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(),restart_lsn)) AS 
replicationSlotLag, active FROM pg_replication_slots ;

-- PostgreSQL v10 及更高版本
SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag, 
active FROM pg_replication_slots ;

这个数据是 DMS 服务同步数据所使用的,之前会通过 DMS 服务将数据同步到 Redshift 分析。

到 DMS 面板查看任务,发现 Task 果然挂了,这就导致 Slots 数据没有人消费和删除,最终一直积累,占用磁盘空间。

因为不需要再同步数据,删除 Task 后,其中一个 Slot 记录消失了,另一条还在,图 2 Active 字段为 False 则代表无人使用,可以删除。

SELECT pg_drop_replication_slot('oxzyegptafscocsv_00016401_756b9db1_c1d6_45bc_a42c_622465811e08');

删除复制槽后,被槽位卡住的 WAL 文件会在后续检查点/归档清理中被回收;一般不需要(也不应指望)用 VACUUM 来释放这类磁盘占用——VACUUM 主要回收表/索引死元组空间,与 replication slot 占用的 WAL 不是同一回事。

参考这篇文章了解 Vacuum:PostgreSQL 学习计划——Vacuum 清理机制

若同时存在大量死元组需要清理,再按需执行 vacuum;需要注意的是会消耗 CPU 及磁盘 IO,如果数据库负载较高,需谨慎操作。

执行后再次查看 “可用磁盘空间面板”,2TB 空间回来了。

参考