You need to enable JavaScript to run this app.
导航
如何排查 PostgreSQL 存储空间占用问题-2
最近更新时间:2022.05.09 18:37:01首次发布时间:
问题描述

我的 RDS for PostgreSQL 占用的存储空间不符合预期,我该如何排查此类问题?

问题分析

RDS for PostgreSQL 消耗的存储空间主要包含如下方面:

  1. 数据文件
  2. WAL 日志
  3. 未消耗的 replication slot
  4. 数据库日志
  5. 临时文件
  6. ……

在我们进行排查此问题时,可以从这个方面进行。在上一个章节[1],我们讲述了如何排查数据占用大小,本节内容会提到下面的几种可能性。

解决方案

WAL 日志

和其他数据库类似,PostgreSQL 也采用了日志先行的方法,即在持久化数据文件前,保证之前的事务日志已经写到磁盘,以此来保证事务的持久性。

下列情况可能会导致事务日志磁盘使用量增加:

  1. 高数据库负荷(数据库有频繁的写入操作)
  2. 只读副本为存储已满状态(在主实例上保留事务日志)
  3. 复制槽

这是需要检查是否由于高负载导致 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_statementlog_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

如果您有其他问题,欢迎您联系火山引擎技术支持服务