复制延迟 - 超过 max_slot_wal_keep_size,WAL 段未删除

Mar*_*icz 5 postgresql replication wal postgresql-13

概括

我们max_slot_wal_keep_size从 Postgresql 13 开始使用来防止 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_sizeWAL 可用?
  • Q2:如果不是,为什么当归档程序和系统上运行的任何事务都不需要过多的 WAL 时,PG 不删除它们?

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

  • Q3:再说一遍——为什么PG没有清除WAL?更明显的是,任何进程都不需要 WAL。

非常感谢!

alv*_*rre 6

这是 PostgreSQL 的一个错误,现已修复。感谢您的举报!

根据发行说明,它应该在 13.4 中可用(查找“提前最旧的所需 WAL 段”)