AWS Postgres RDS磁盘使用率突增排查:排除MVCC与Vacuum后的其他原因
这种突发的磁盘使用率飙升确实让人头大,尤其是已经排除了MVCC和Vacuum的常见因素之后。结合AWS RDS Postgres的环境特性,我整理了几个容易被忽略的排查方向:
1. 临时文件(Temporary Files)大规模生成
Postgres在执行复杂查询时(比如大结果集排序、哈希连接、创建索引、批量数据导入),会在pg_temp目录生成临时文件。如果突然出现大量这类查询(比如定时任务跑了未优化的报表查询,或者程序逻辑错误触发了全表扫描+排序),这些临时文件会瞬间占满磁盘。
你可以通过以下方式排查:
- 查看Postgres日志里包含
temp_file_size的条目,找到生成大临时文件的查询; - 用
SELECT pid, query, temp_bytes FROM pg_stat_activity WHERE temp_bytes > 0 ORDER BY temp_bytes DESC;实时查看正在生成临时文件的进程; - 用
SELECT datname, temp_files, temp_bytes FROM pg_stat_database;统计各数据库的临时文件总占用。
2. WAL日志异常堆积
虽然RDS会自动管理WAL日志,但以下场景会导致WAL文件无法被清理,持续占用磁盘:
- 只读副本出现同步故障(比如副本离线、网络延迟过高),主库需要保留WAL等待副本同步;
archive_mode开启但归档失败(比如S3存储桶权限配置错误、归档进程异常),WAL文件会一直堆积。
排查方式:
- 在RDS控制台查看“只读副本”的同步状态(比如复制延迟、是否正常运行);
- 用
SELECT pg_current_wal_lsn(), pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();检查副本的同步进度; - 查看CloudWatch指标中的
WALDiskUsage,确认WAL目录的占用趋势。
3. 意外的本地备份或数据导出
RDS的自动备份会存储在S3中,不会占用实例磁盘,但如果有人手动执行了pg_dump或psql导入/导出操作,并且将文件保存到实例本地(比如默认的/home/rdsadmin目录),这些大文件会快速耗尽磁盘空间。
可以通过RDS的“系统日志”或者执行SELECT * FROM pg_stat_activity WHERE query LIKE '%pg_dump%' OR query LIKE '%copy%';查看是否有这类操作。
4. 日志文件暴增
如果Postgres的日志级别被设置为debug或log_min_messages过低,或者实例突然出现大量错误(比如频繁的连接失败、查询语法错误),日志文件会迅速膨胀。RDS默认会轮转日志,但如果错误量极大,轮转后的日志文件也会占用大量空间。
你可以在RDS控制台的“日志和监控”中查看日志文件的大小,或者直接下载日志查看是否有异常的重复报错。
5. 逻辑复制相关文件堆积
如果实例开启了逻辑复制(比如使用pg_logical或CDC工具),如果复制槽(replication slot)未被及时清理,或者订阅端故障,pg_logical目录会堆积大量未消费的WAL数据,导致磁盘占用飙升。
排查命令:SELECT slot_name, plugin, slot_type, active, pg_size_pretty(pg_slot_size(slot_name)) FROM pg_replication_slots;,查看是否有非活跃的复制槽占用大量空间。
6. RDS内部维护残留文件
偶尔RDS的自动维护操作(比如版本升级、补丁安装、快照预准备)会生成临时文件,如果维护过程异常中断,这些文件可能残留并占用磁盘空间。这种情况比较少见,但可以通过CloudWatch的DiskUsage指标结合维护事件时间线来排查。
内容的提问来源于stack exchange,提问作者Joddy

