【问题标题】:How to limit WAL size when using Postgres Logical Replication Slot?使用 Postgres 逻辑复制槽时如何限制 WAL 大小?
【发布时间】:2023-03-27 15:09:01
【问题描述】:

我正在创建复制槽并通过 JDBC 驱动程序从 AWS Postgres RDS 将更改流式传输到 java 进程。

我的复制槽创建代码如下所示。

final ReplicationSlotInfo replicationSlotInfo = pgConnection.getReplicationAPI()
                    .createReplicationSlot()
                    .logical()
                    .withSlotName(replicationSlotName)
                    .withOutputPlugin("wal2json")
                    .make();

我使用以下代码获得复制流。

pgConnection.getReplicationAPI()
                .replicationStream()
                .logical()
                .withSlotName(replicationSlotName)
                .withSlotOption("include-xids", true)
                .withSlotOption("include-timestamp", true)
                .withSlotOption("pretty-print", false)
                .withSlotOption("add-tables", "public.users")
                .withStatusInterval(10, TimeUnit.SECONDS)
                .start()

当复制器 java 进程未运行时,WAL 大小会增加。这是我用来查找复制滞后的查询。

SELECT
    slot_name,
    pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)) AS replicationSlotLag,
    active
FROM
    pg_replication_slots;

输出:

slot_name   replicationslotlag  active
data_stream_slot    100 GB  f

这种复制延迟会增加,超出 RDS 磁盘,这会关闭 RDS。

我认为wal_keep_segments 会处理这个设置为 32 的问题。但它不起作用。 是否有任何其他属性我必须设置以避免这种情况,即使 Java 复制进程没有运行。

【问题讨论】:

  • 在 Postgres 13 中,您现在可以limit 为复制槽保留 WAL 的大小

标签: postgresql jdbc replication logical-replication


【解决方案1】:

a proposal 允许限制逻辑复制槽 WAL 保留。我认为这正是您所需要的,但尚不清楚何时/是否可用。

与此同时,您所能做的就是监视情况,然后如果它开始落后太远就放弃该插槽。当然,这确实意味着您稍后在重新建立同步时会遇到问题,但没有办法解决这个问题(除了修复导致复制过程消失和/或落后的任何问题)。

既然你说java进程没有运行,那么删除slot很容易。如果它正在运行,但只是没有跟上,那么您将不得不在杀死 wal 发件人的地方跳一段悲伤的小舞,然后尝试在插槽重新启动之前放下插槽(我不知道您是如何做到的) RDS)

wal_keep_segments只适用于物理复制,不适用于逻辑。它是用于使用 而不是 插槽,而不是除了它们。如果两者都有,则保留 WAL 直到满足 两个 条件。确实,这就是您面临的问题;逻辑复制不能像物理复制那样不使用槽来完成。

【讨论】:

【解决方案2】:

wal_keep_segments 与逻辑解码无关。

使用逻辑解码,你总是必须使用一个逻辑复制槽,这是一种在事务日志(WAL)中标记位置的数据结构,这样服务器就不会丢弃旧的 WAL 段那个逻辑解码可能仍然需要。

这就是如果您不使用更改,您的 WAL 目录会增长的原因。

wal_keep_segments 指定要保留的旧 WAL 段的最小 数量。它用于流复制、pg_receivewalpg_rewind 等目的。

【讨论】:

  • 如果 wal_keep_segments 无关紧要,你知道在使用复制槽时如何限制 WAL。我认为应该有一个简单的属性来限制 WAL 的大小。当复制过程停止时,我不在乎 Postgres 是否删除了旧的 WAL。
  • 使用复制槽时不能限制 WAL 的数量。您必须监控消费者并确保它不会落后。
【解决方案3】:

wal_keep_segments 指定 PostgreSQL 应在pg_xlog 目录中保留的最小 段数。 PostgreSQL 不删除段可能有几个原因:

  1. 在比 WAL 文件更旧的 WAL 位置有一个复制槽,您可以使用以下查询进行检查:
SELECT slot_name,
       lpad((pg_control_checkpoint()).timeline_id::text, 8, '0') ||
       lpad(split_part(restart_lsn::text, '/', 1), 8, '0') ||
       lpad(substr(split_part(restart_lsn::text, '/', 2), 1, 2), 8, '0')
       AS wal_file
FROM pg_replication_slots;
  1. WAL 归档已启用,archive_command 失败。在这种情况下,请检查 PostgreSQL 日志。

  2. 很久没有checkpoint了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2020-01-01
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多