复制滞后 - 超过 max_slot_wal_keep_size,未删除 WAL 段

Posted

技术标签:

【中文标题】复制滞后 - 超过 max_slot_wal_keep_size,未删除 WAL 段【英文标题】:Replication lag - exceeding max_slot_wal_keep_size, WAL segments not removed 【发布时间】:2021-09-19 15:55:40 【问题描述】:

总结

我们使用 Postgresql 13 中的 max_slot_wal_keep_size 来防止 master 被滞后的复制杀死。看起来,在我们的例子中,WAL 存储在超过这个参数后没有被释放,这导致了复制失败。我认为应该释放的 WAL 似乎一次不需要任何其他交易。我想知道这应该如何工作以及为什么没有删除 WAL 段?

请在下面找到详细信息。

配置

主副本和一个副本 - 使用插槽的流式复制 ~700GB 可用于 pg_wal max_slot_wal_keep_size = 600GB min_wal_size = 20GB max_wal_size = 40GB 默认checkpoint_timeout = 5 分钟(检查点没问题) 归档正在进行中,并且进展顺利

发生了什么

在重负载(大型 COPY/INSERT 事务,加载数百 GB 数据)下,复制开始落后。 pg_wal 上的可用空间以与 safe_slot pg_replication_slot.safe_wal_size 相同的速度减少 - 正如预期的那样。在某些时候safe_wal_size 变得消极,流媒体停止工作。这不是问题,因为副本开始从 WAL 存档恢复。我预计一旦插槽丢失,WAL 将被删除至max_wal_size。然而这并没有发生。似乎 Postgres 试图保持接近max_slot_wal_keep_size(600GB)的可用值,以防副本再次开始追赶。随着时间的推移,没有单一的交易需要保留这么多的 WAL。归档也不落后。

Q1: PG 是否会尝试维持max_slot_keep_size 的 WAL 可用? Q2:如果不是,为什么 PG 在归档器和系统上运行的任何事务都不需要它们时没有删除过多的 WAL?

大部分时间 pg_wal 上的可用空间量大约为 70GB,但是在某些时候,在大量自动清理期间,它下降到 0 :( 这是 PG 崩溃并(不久后自动恢复)的时候。之后备份起来,pg_wal 上还剩下 11GB 并且没有事务运行,没有加载。这持续了几个小时。在此期间,副本终于赶上了存档并立即恢复了复制。没有任何 WAL 被删除。我手动运行检查点,但它没有清除任何 WAL。我终于重新启动了 Postgresql,并且在重新启动期间 pg_wal 终于被清除了。

Q3:再一次 - 为什么 PG 没有清除 WAL?更明显的是,任何流程都不需要 WAL。

非常感谢!

【问题讨论】:

【参考方案1】:

这是一个 PostgreSQL 错误,现在是 fixed。感谢您的报告!

【讨论】:

以上是关于复制滞后 - 超过 max_slot_wal_keep_size,未删除 WAL 段的主要内容,如果未能解决你的问题,请参考以下文章

复制当前行或滞后行

ValueError:无法将大小为0的序列复制到维度为56的数组轴

滞后函数 - 为最后一个值创建虚拟行?

Swift,将更多数据加载到表视图中会导致滚动滞后

SQL Server:跨组(而不是组内)的领先/滞后分析功能

mySQL 复制是不是具有即时数据一致性?