You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TimescaleDB多副本Active Slot错误求助:复制槽占用问题

问题根源分析

你的报错核心在于:PostgreSQL/TimescaleDB的复制槽是一对一独占资源,单个复制槽无法同时被多个从节点的WAL流复制连接占用。pg-slave1已通过PID121占用了r1_slot,pg-slave2尝试复用同一个槽时必然触发冲突,导致无法启动WAL流。

解决步骤

1. 停止冲突的从节点容器

先暂停两个从节点,避免持续产生连接冲突:

docker-compose stop pg-slave1 pg-slave2

2. 在主节点创建独立复制槽

进入pg-master容器,为每个从节点创建专属的复制槽:

docker-compose exec pg-master psql -U postgres

在psql命令行中执行:

-- 为pg-slave1创建专属复制槽
SELECT pg_create_physical_replication_slot('r1_slot');
-- 为pg-slave2创建专属复制槽
SELECT pg_create_physical_replication_slot('r2_slot');

执行完成后退出psql:\q

3. 修改从节点的复制配置

3.1 调整replication.sh脚本

找到脚本中指定复制槽的逻辑,确保每个从节点使用对应专属槽:

  • pg-slave1对应r1_slot
  • pg-slave2对应r2_slot

示例修改后的WAL流启动命令:

# pg-slave1的初始化命令
pg_basebackup -h pg-master -U replicator -D /var/lib/postgresql/data -P -X stream -S r1_slot

# pg-slave2的初始化命令
pg_basebackup -h pg-master -U replicator -D /var/lib/postgresql/data -P -X stream -S r2_slot

3.2 调整docker-compose.yml

通过环境变量为每个从节点传递专属复制槽名称,避免硬编码:

services:
  pg-slave1:
    ...
    environment:
      - REPLICATION_SLOT=r1_slot
  pg-slave2:
    ...
    environment:
      - REPLICATION_SLOT=r2_slot

4. 清理旧复制数据(可选)

如果从节点已有旧的复制残留数据,建议清空后重新初始化:

# 清理pg-slave1的数据目录
docker-compose run --rm pg-slave1 rm -rf /var/lib/postgresql/data/*
# 清理pg-slave2的数据目录
docker-compose run --rm pg-slave2 rm -rf /var/lib/postgresql/data/*

5. 重启所有节点

docker-compose up -d pg-master pg-slave1 pg-slave2

6. 验证复制状态

进入主节点检查复制槽占用情况,确认两个槽分别绑定不同进程:

docker-compose exec pg-master psql -U postgres -c "SELECT slot_name, active, pid FROM pg_replication_slots;"

正常情况下,r1_slot和r2_slot的active状态为t,且对应不同的PID。

预防措施
  • 每个从节点必须使用唯一的复制槽名称,复制槽是主节点的独占资源,不可共享
  • 在replication.sh中通过环境变量动态获取复制槽名称,避免硬编码
  • 主节点postgresql.conf中max_replication_slots参数值需大于等于从节点数量(比如2个从节点时,设置max_replication_slots = 3留冗余)

内容的提问来源于stack exchange,提问作者SefaUn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:55:05