PostgreSQL 教程: 处理服务器磁盘满的问题

二月 28, 2025

摘要:在本教程中,您将学习如何排查 PostgreSQL 服务器磁盘满的问题。

目录

背景

如果 PostgreSQL 的磁盘空间已用完,则需要注意一些事项。根据服务器配置,可能有多个设备在运行,因此您的数据目录、表空间、日志或 WAL 目录都可能会受到影响。

磁盘空间已满的原因会有很多,以下是一些常见的可能原因:

  • archive_command 执行失败,WAL 文件正在填满磁盘空间。
  • 备用数据库的连接已断开,复制槽还存在,这会导致 WAL 填满磁盘。
  • 大型数据库的更改生成太多的 WAL,以至于它占用了所有可用的磁盘空间。
  • 您实际上刚好用完了存储数据的磁盘空间,而您的监控程序和警报并没有通知到您。

对整个数据库系统最不利的情况是 WAL 目录已满。这会导致应用程序再也无法对数据库系统进行更改,因为它无法记录 WAL 更改。然后 PostgreSQL 别无选择,只能发出 PANIC 并关闭。

如您所见,其中许多情况都与 WAL 填满磁盘有关。关闭数据库将使您处于危险的境地,因此这就是我们将在这篇文章中深入研究的地方。

不该做什么

切勿删除 WAL

看到 WAL 填满您的磁盘空间时,一种常见的下意识反应是删除这些日志文件。这是系统管理员非常常见的方法:大日志文件填满了磁盘,那就删除它们,对吧?但是,WAL 不只是普通的系统日志。它们是启动和运行 PostgreSQL 不可或缺的一部分,删除 WAL 会损坏您的数据库。

请记住,一旦 PostgreSQL 正常运行,在它已经验证过不再需要这些 WAL 文件后(也就是,确认它已经成功归档了这些文件),它本身就会删除额外的 WAL 文件。

如果您删除 WAL 文件,则可以保证您的数据库将会处于不一致的状态,数据库会损坏。所以,永远不要删除 WAL 文件!

不要立即用备份还原来覆盖现有的数据目录

在最好的情况下,当您用备份来恢复时,您已经确定了您可以接受数据丢失,因为您实际上是选择了放弃自上次备份以来的任何数据库更改。用备份来恢复是一种灾难恢复方法,通常意味着在整个系统无法运行或数据文件已损坏的情况下,才会使用这种方法;也就是,出现真正灾难的时候。

特别是,如果您的 archive_command 执行失败,这意味着您将会丢弃掉自上次成功备份以来数据库中发生的所有事务。这是关键:如果 archive_command 执行失败,这些也会用于基础备份,则无法保证上次备份的期限。您需要监控好您的备份和 archive_commands 的运行。

如果确实需要,可以进行备份还原,但这不应该是在您发现问题时首先去采用的方法。

不要简单地就地调整大小

因为生产业务停止了运行,您显然会渴望尽快解决这个问题。虽然您对磁盘空间不足的下意识反应是添加更多存储空间,但通常最好申请一个新的更大的实例,并在其中进行还原,而不是尝试就地调整大小。首先,也是最重要的一点是,我们希望将损坏的实例保留在原位,以便以后还可以访问它;此时,可能不清楚问题的真正原因是什么。保留任何已停止工作的生产实例,是执行事后分析的最佳方式,这也可以让我们对任何新的业务系统的完整性充满信心。

注意:这是一个比其他要求更柔和的一个 “建议”;如果这是启动和运行数据库的唯一选择,则此方法应该是可以正常修复问题的。

应该做什么

立即进行文件系统层的备份

请确保 PostgreSQL 已停止运行,并在执行任何操作之前,备份 PostgreSQL 数据目录(包括 pg_wal 目录和任何非默认的表空间),以便在需要时可以返回到此状态。在修复 PostgreSQL 和 WAL 归档时,有很多不同的事情可能会出错,因此能够保留尽可能多的原始证据/状态,既可以在重建过程中保护您,也可以为确定根本原因提供有价值的取证数据。

任何可以完成文件系统层备份的方法都是可能的;您可以使用离线备份、文件系统级快照、rsync 到远程服务器、tarball 打包等方法。

创建具有足够空间的新实例(或至少一个新的磁盘)

我们建议尽可能还原到新实例。如果您能够使用刚刚创建的备份,则可以在确保新实例上的所有配置、路径等都正确无误后,测试恢复此备份。如果要在新实例上安装数据库,还要确保您使用的是相同的 PostgreSQL 版本(包括其他软件包和扩展),并且区域设置具有相同的设置。

现在,您已经消除了磁盘空间问题,您应该能够恢复数据库操作了。

修复底层问题

现在数据库已备份并运行,请查看日志以了解失败的原因,并修复底层的问题。现在请添加/调整您的监控,以便您将来能够检测和防止此问题。例如,如果这是由 archive_command 执行失败引起的 ,您可以利用一些日志分析工具,来通知您此类事情是否再次开始发生。

总结一下,如果您要移除某些文件,请不要删除您的 WAL 文件。如果您的磁盘已满,PostgreSQL 提供了可帮助您快速高效恢复的工具。

了解更多

PostgreSQL 管理

处理 pg_wal 目录中的 WAL 积压