我的 RDS for PostgreSQL 占用的存储空间不符合预期,我该如何排查此类问题?
RDS for PostgreSQL 消耗的存储空间主要包含如下方面:
- 数据文件
- WAL 日志
- 未消耗的 replication slot
- 数据库日志
- 临时文件
- ……
在我们进行排查此问题时,可以从这个方面进行。在上一个章节[1],我们讲述了如何排查数据占用大小,本节内容会提到下面的几种可能性。
WAL 日志
和其他数据库类似,PostgreSQL 也采用了日志先行的方法,即在持久化数据文件前,保证之前的事务日志已经写到磁盘,以此来保证事务的持久性。 下列情况可能会导致事务日志磁盘使用量增加:
- 高数据库负荷(数据库有频繁的写入操作)
- 只读副本为存储已满状态(在主实例上保留事务日志)
- 复制槽
这是需要检查是否由于高负载导致 WAL 日志占用大量磁盘空间,同时需要检查只读副本是否处于正常工作状态,排除是否存储空间已满,复制延迟高等影响因素。
replication slot
如果存在 replication slot 但是没有目标端进行消费,占用的空间不会被回收。通常来说,在我们迁移上云时,使用 DTS 迁移工具进行逻辑复制会使用到 replication slot。 我们可以执行与以下查询以确认复制槽存在及其大小:
postgres=# select slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) as replicationSlotLag,
active from pg_replication_slots ;
slot_name | replicationslotlag | active
--------------------------------------------+--------------------+--------
postgres_18202f19b5ffe5b1_746cc768bc_fkv7g | 0 bytes | t
postgres_5d05ec693d92_84788bfb5_l8q6k | 0 bytes | t
(2 rows)
当发现 active 为 FALSE 的 slot 之后,我们可以使用如下语句来进行删除,以此来释放磁盘空间:
postgres=# select pg_drop_replication_slot('slot_name');
日志文件
在往期的文章中[1],我们提到两个 PostgreSQL 日志相关参数,分别为 log_statement 和 log_min_duration_statement,不同的参数设置可能会导致磁盘空间占用超出预期。请检查这个两个参数是否符合预期。
临时文件
临时文件可能会在排序,hash,和存储临时结果时创建。我们可以使用如下 SQL 语句来监控临时文件的占用情况
psql> SELECT datname, temp_files AS "Temporary files",temp_bytes AS "Size of temporary files" FROM pg_stat_database ;
不过需要注意的是, temp_files 和 temp_bytes 是自实例启动以来的累计值,需要多次运行上述查询来确定一段时间内的增量,而不是只看输出。 在 PostgreSQL 中,log_temp_files 参数控制临时文件名称和大小的日志记录活动。如果您将 log_temp_files 值设置为 0,则将记录所有临时文件信息。如果您将参数设置为正值,则只记录大于或等于指定字节数的文件大小。
[1] 如何排查 PostgreSQL 存储空间占用问题-1 [2] https://www.postgresql.org/docs/11/runtime-config-logging.html 如果您有其他问题,欢迎您联系火山引擎技术支持服务