问题是,如果复制副本完全死亡并且在很长一段时间内不能恢复;或者复制副本被销毁并且DBA忘记删除复制插槽;或者该插槽是某个实验遗留下来的被遗忘的插槽;或者甚至复制副本是通过慢速网络链路馈送的,那么保留的WAL将无限增长。那就变成了定时炸弹。
为了解决这个问题,本口京太郎自2017年2月以来一直在PostgreSQL补丁中工作,以限制插槽保留的WAL的大小。在经历了非常长的审查和返工过程之后,我将其集成到PostgreSQL 13中,改进了高可用性PostgreSQL场的管理。
主要原则是杀死一个副本(通过以某种方式使其插槽无效;下面将详细介绍),而不是杀死为该副本提供数据的主服务器,然后将所有生产一起关闭。
它的工作方式非常简单:将postgresql.conf中的max_lot_wal_Keep_size(文档)设置为允许复制槽保留的最大WAL磁盘空间量。如果插槽到达该点并出现检查点,则该插槽将被标记为无效,并且某些WAL文件可能会被删除。如果时隙正在被Walsender进程有效使用,则该进程将被发信号通知,以便其终止。如果walsender重新启动,它会发现必要的wal文件将不再存在。必须重新克隆使用该插槽的复制副本。
如果max_lot_wal_Keep_size为0(默认值),则没有限制。我不建议这样做,因为当插槽填满磁盘时,它会导致故障。
还包括一些监控功能。PG_REPLICATION_SLOTS中的两列是相关的。最关键的是WAL_STATUS。如果该列是保留的,则该槽指向max_wal_size内的数据;如果它被扩展,则它超过了max_wal_size,但仍受wal_Keep_size或max_lot_wal_Keep_size保护(包括当max_lot_wal_Keep_size为零时)。任何一种状态都是好的和正常的。然而,当插槽超过限制时,它首先变成无保留状态,这意味着它处于迫在眉睫的危险之中,但如果它足够快,它仍然可以恢复。最后,当WAL文件已删除且无法恢复π时,状态会丢失。
另一列是SAFE_WAL_SIZE:它显示在此槽处于删除WAL文件的危险之前可以写入的WAL字节数。我们建议您密切关注您的监控系统中的这一列,并在它变低时发出警报。零或负表示您的复制副本将在检查点发生后立即失效:
我们相信,这一新功能使副本的维护变得更容易、更健壮;希望我们不会因为这些问题而看到更多生产停产的灾难。
(注意:SAFE_WAL_SIZE是在13beta3中引入的,因此请务必查阅最新文档,否则您将看到MIN_SAFE_LSN。忽略这一点。)。
特别感谢本口京太郎为解决这个问题所做的努力。几位评论家对此深有感触,其中我要特别感谢的是泽田雅彦、藤井正雄、吉隆·德罗特莱和阿米特·卡皮拉(顺序不分先后)。