Patroni 4.1.5 配置参数详解

patroni.yml 两配置域(本地 vs DCS 动态)边界、HA 三大节拍 ttl/loop_wait/retry_timeout 机制、edit-config/show-config/REST 修改通道全实测,附生产配置模板与 8 条 FAQ(16GB/SSD/OLTP 基线)。

PatroniPatroni2026/10/20

Patroni 4.1.5 配置参数详解

目标:逐项讲透 Patroni 4.1.5 的 patroni.yml 配置体系——节点本地配置与 DCS 动态配置两个域的边界、HA 三大节拍参数(ttl/loop_wait/retry_timeout)的作用机制、每个核心段的取值与生产建议,以及参数修改的三种通道(文件重启、patronictl edit-config、REST API)。全文基于 3 节点 etcd + Patroni 4.1.5 + PostgreSQL 17.11 集群实测(实测环境与部署过程见《Patroni 4.1.5 3 节点高可用集群部署指南》,实测日期 2026-10-20)。

一、环境信息

项目值
集群pgdemo:pgnode1(10.89.60.11)/ pgnode2(10.89.60.12)/ pgnode3(10.89.60.13),1 主 2 从
操作系统Ubuntu 22.04(jammy),Python 3.10.12
Patroni4.1.5(patroni --version 实测)
PostgreSQL17.11(PGDG)
DCSetcd v3.5.21(三节点,etcd3 驱动段连接)
配置文件每节点 /etc/patroni/patroni.yml(属主 root,组 postgres,640)
配置基线假设本文生产模板按 16GB 内存 / 512GB SSD / 8 vCPU / OLTP 读写混合负载 的通用主机配置给出
systemdpatroni.service(PATRONICTL_CONFIG_FILE=/etc/patroni/patroni.yml、MALLOC_ARENA_MAX=1)

二、前置条件

  1. 已按部署篇完成 3 节点集群并处于健康态(patronictl list 显示 1 Leader + 2 Replica streaming)。
  2. 每节点 /etc/patroni/patroni.yml 内容与部署篇 4.5 节一致;patronictl 通过 -c 指定或经环境变量 PATRONICTL_CONFIG_FILE 定位该文件。
  3. 修改 DCS 动态配置前,建议先备份当前生效配置:
patronictl -c /etc/patroni/patroni.yml show-config > /root/patroni-dcs-backup.yml

三、两个配置域:本地配置 vs DCS 动态配置

Patroni 的配置分属两个域,边界搞不清是新手最大的误区:

域存放位置生效范围生效方式典型内容
节点本地配置每节点 /etc/patroni/patroni.yml仅本节点改文件后重启 patroni(systemctl restart)或 patronictl reload节点名、监听地址、etcd3 连接、认证凭据、data_dir、tags
DCS 动态配置etcd 中 scope 对应的 /service/pgdemo/config key全集群所有节点patronictl edit-config 或 REST PATCH,自动分发ttl/loop_wait/retry_timeout、maximum_lag_on_failover、PG parameters、pg_hba
  • bootstrap.dcs: 段在文件里只是首次引导时的初始值——集群初始化后,DCS 动态配置以 etcd 中存储的为准,后续改文件里的 bootstrap.dcs 不会再生效(这也是 FAQ 4 的根源)。
  • 节点本地参数(如 name、connect_address)改错了会导致节点身份错乱,必须逐台谨慎修改并重启。

3.1 查看动态配置:show-config 与 REST API

在 pgnode1 上执行:

patronictl -c /etc/patroni/patroni.yml show-config

实测回显(pgdemo 集群当前生效的完整动态配置):

loop_wait: 10
maximum_lag_on_failover: 1048576
postgresql:
  parameters:
    hot_standby: 'on'
    max_replication_slots: 10
    max_wal_senders: 10
    wal_level: replica
    wal_log_hints: 'on'
  pg_hba:
  - local all postgres peer
  - local all all peer
  - host all all 127.0.0.1/32 scram-sha-256
  - host all all ::1/128 scram-sha-256
  - host replication replicator 10.89.60.0/24 scram-sha-256
  - host all all 10.89.60.0/24 scram-sha-256
  use_pg_rewind: true
retry_timeout: 10
ttl: 30

等价的 REST 方式(在 pgnode2 上执行):

curl -s http://10.89.60.11:8008/config

实测回显(JSON 形式,内容与 show-config 一致):

{"ttl": 30, "loop_wait": 10, "retry_timeout": 10, "maximum_lag_on_failover": 1048576, "postgresql": {"use_pg_rewind": true, "parameters": {"wal_level": "replica", "hot_standby": "on", "max_wal_senders": 10, "max_replication_slots": 10, "wal_log_hints": "on"}, "pg_hba": ["local all postgres peer", "local all all peer", "host all all 127.0.0.1/32 scram-sha-256", "host all all ::1/128 scram-sha-256", "host replication replicator 10.89.60.0/24 scram-sha-256", "host all all 10.89.60.0/24 scram-sha-256"]}}

3.2 修改动态配置:patronictl edit-config

edit-config 支持三种形态:交互式编辑器全量改(无参数)、键值直改(-s/-p)、文件灌入(-f)。完整参数(patronictl edit-config --help 实测):

  cluster_name           The name of the cluster
  -f FILE, --file FILE   Apply changes from an existing file to the cluster's DCS configuration
  -s SET, --set SET      Set specific configuration value. It has the highest priority. Can be repeated. Example: -s ttl=100
  -p SET, --pg SET       Set specific postgresql parameter. It has the second-highest priority. Can be repeated. Example: -p max_connections=100
  -r SET, --remove SET   Remove configuration parameter. Can be repeated. Example: -r postgresql.use_slots
  --force                Apply changes without showing them and without confirmation
  -q, --quiet            Do not show changes
  -y, --yes              Apply changes without confirmation

以把主库的 WAL 发送进程上限从 10 调到 12 为例(在 pgnode1 上执行):

patronictl -c /etc/patroni/patroni.yml edit-config pgdemo -p max_wal_senders=12

实测回显( Patroni 自动生成 diff 并请求确认;--force 可跳过确认):

---
+++
@@ -4,7 +4,7 @@
   parameters:
     hot_standby: 'on'
     max_replication_slots: 10
-    max_wal_senders: 10
+    max_wal_senders: 12
     wal_level: replica
     wal_log_hints: 'on'
   pg_hba:
Configuration changed

3.3 参数生效链路与 pending restart

动态配置下发后,Patroni 在下一个 loop_wait(10 秒)周期内向 postgres 发送 pg_ctl reload(SIGHUP)。无需重启即可生效的参数(如 work_mem)立即生效;必须重启的参数(如 max_wal_senders)会出现两条证据链(实测回显):

  1. PostgreSQL 日志(journalctl -u patroni 可见):
Oct 19 16:58:58 pgnode1 patroni[7876]: 2026-10-19 16:58:58.827 UTC [7876] LOG:  parameter "max_wal_senders" cannot be changed without restarting the server
  1. Patroni 日志记录变更,节点进入 Pending restart 状态:
Oct 19 16:59:12 pgnode1 patroni[7849]: 2026-10-19 16:59:12,042 INFO: Changed max_wal_senders from '10' to '12'

patronictl list 的 Pending restart 列出现星号;在维护窗口重启该节点进程消除:

patronictl -c /etc/patroni/patroni.yml restart pgdemo pgnode1 --force

用 systemctl status patroni 可以直接看到新参数已被写进 postgres 启动命令行(实测回显,节选):

├─7876 /usr/lib/postgresql/17/bin/postgres -D /var/lib/postgresql/17/pgdemo --config-file=/var/lib/postgresql/17/pgdemo/postgresql.conf --listen_addresses=0.0.0.0 --port=5432 --cluster_name=pgdemo --wal_level=replica --hot_standby=on --max_connections=100 --max_wal_senders=12 --max_prepared_transactions=0 --max_locks_per_transaction=64 --track_commit_timestamp=off --max_replication_slots=10 --max_worker_processes=8 --wal_log_hints=on

四、配置结构总览

patroni.yml 的顶层结构一览(标注每个段属于本地域还是 DCS 域):

配置段域作用
scope / namespace / name本地集群名 / key 前缀 / 节点名
restapi本地REST API 监听与 TLS
etcd3(或 consul/zookeeper/kubernetes/raft)本地DCS 连接信息(五选一)
bootstrap.dcsDCS(仅首次引导)动态配置初始值
bootstrap.initdb / bootstrap.method / bootstrap.post_bootstrap本地(仅首次引导)首节点初始化行为
postgresql本地PG 实例管理:目录、监听、认证、本地参数
tags本地节点角色微调
watchdog / ssl / standby_cluster / citus本地高级特性开关

五、核心参数详解

5.1 节点标识段:scope / namespace / name

scope: pgdemo          # 集群名:etcd 中 /service/pgdemo/* 之下的 key 归属本集群
namespace: /service/   # key 空间前缀;同一路 DCS 跑多套集群时用不同 namespace 隔离
name: pgnode1          # 本节点全局唯一名,出现在 patronictl list 与 REST API 中

实测说明:三节点 scope 必须一致(否则视为不同集群互不感知);name 全局唯一(重复会导致选主混乱)。本集群 etcd 内实际的 key 空间为 /service/pgdemo/(etcdctl get /service/pgdemo/ --prefix 可见 leader/leader-optime/history/config/failover/initialize/members 等子键)。

5.2 restapi 段

restapi:
  listen: 0.0.0.0:8008        # REST API 监听地址与端口
  connect_address: 10.89.60.11:8008   # 本节点对外宣告的 REST 地址(其他节点用它连自己)
  # verify_client: none       # 证书校验模式:none/optional/required(配 ssl 段使用)
  # authentication:           # 开启后 patronictl/REST 需 Basic 认证
  #   username: admin
  #   password: q1w2e3r4

实测说明:8008 端口同时承担三重职责——节点互访通道、HAProxy 健康检查端点(/primary /replica)、运维 API。connect_address 必须是其他节点可达的 IP,写 127.0.0.1 是新手常见错误(会导致集群互访失败)。

5.3 DCS 连接段:etcd3

etcd3:
  hosts: 10.89.60.11:2379,10.89.60.12:2379,10.89.60.13:2379   # etcd 集群全部成员,逗号分隔

实测说明:

  • hosts 务必写全三台 etcd——Patroni 任一时刻只需连上法定人数即可工作,写全单台 etcd 宕机才不影响集群。
  • 驱动来源:官方 README 依赖清单(2026-10-20 实查)etcd3 extra 对应 python-etcd 包,pip install patroni[etcd3] 已随 Patroni 安装。
  • 备选 DCS 段(同位置二选一):consul:(py-consul)、zookeeper:(kazoo)、kubernetes:(k8s API)、raft:(pysyncobj,仅测试)。切换 DCS 时 Patroni 侧只需替换本段。

5.4 bootstrap.dcs 段:集群动态配置初始值(含 HA 三大节拍)

bootstrap:
  dcs:
    ttl: 30                       # 领导者租约时长(秒)
    loop_wait: 10                 # 主循环轮询周期(秒)
    retry_timeout: 10             # 对 DCS/PG 操作的重试超时(秒)
    maximum_lag_on_failover: 1048576   # 候选从库最大落后字节数(1MB)
    postgresql:
      use_pg_rewind: true         # 允许用 pg_rewind 回卷旧主
      use_slots: true             # 使用物理复制槽保护 WAL(默认 true)
      parameters:                 # 写入 postgresql.conf 的参数(DCS 动态管理)
        wal_level: replica
        hot_standby: 'on'
        max_wal_senders: 10
        max_replication_slots: 10
        wal_log_hints: 'on'
      pg_hba:                     # 初始 pg_hba 规则(DCS 动态管理)
        - local all postgres peer
        - local all all peer
        - host all all 127.0.0.1/32 scram-sha-256
        - host all all ::1/128 scram-sha-256
        - host replication replicator 10.89.60.0/24 scram-sha-256
        - host all all 10.89.60.0/24 scram-sha-256

三大节拍参数是整个 HA 行为的骨架,三者关系与失效判定:

参数默认实测取值作用与影响
ttl3030leader key 租约秒数。主库 Patroni 持续续约;ttl 秒内无法续约即判主库失联,触发选主。调小→切换更快但抖动误切风险高
loop_wait1010每个节点检查集群状态/应用配置的周期。动态配置、角色变化都要等 1 个周期生效;调小→响应快、DCS 压力大
retry_timeout1010单次对 DCS/PG 请求的重试超时。跨机房部署建议大于单程网络延迟(如机房间 5ms 以上延迟时设 15–30)

💡 技术拓展:自动故障转移的总时长 ≈ ttl(租约过期)+ loop_wait(下一周期发现)+ promote 时间(秒级)。部署篇实测主库 Patroni 被停止后 约 16 秒完成自动提升(16:43:29 history 时间戳减去停库时间),与该公式吻合(本例租约在 30s 内被余下节点检测到空缺)。跨机房场景建议 ttl=60、retry_timeout=30,宁可慢切不可误切。

其他关键项:

  • maximum_lag_on_failover:候选从库 replay_lsn 落后超过 1MB 就放弃竞选(宁可停止服务也不丢数据)。
  • use_pg_rewind: true:必须配合 PG 参数 wal_log_hints: on(或 initdb 加 data-checksums,部署篇两者都配了)。
  • pg_hba:必须含 127.0.0.1/32 与 ::1/128,否则首次引导即失败(部署篇 FAQ 2 实录:no pg_hba.conf entry for host "127.0.0.1")。
  • 可选参数 max_timelines_history(时间线历史保留条数)、check_timeline(加入节点时间线校验)等按需追加。

5.5 bootstrap 段:首节点初始化(仅首次引导有效)

bootstrap:
  dcs: {…}                     # 见 5.4
  initdb:                      # 首节点 initdb 参数列表
    - encoding: UTF8
    - data-checksums           # 开启数据校验和(也是 pg_rewind 的前提之一)
  # post_bootstrap: /var/lib/postgresql/init_user.sh   # 引导完成后执行的脚本(4.0 起创建业务用户的正确姿势)
  # method:                    # 从库克隆方式,默认 pg_basebackup,可扩展 wal_g/pgbackrest
  #   pg_basebackup:
  #     max_rate: 100M
  #     network_partition_timeout: 10

实测说明(重要变更):Patroni 4.0 起 bootstrap.users 已移除,配置该段不再生效(部署篇实测日志原文:ERROR: User creation is not be supported starting from v4.0.0. Please use "bootstrap.post_bootstrap" script to create users.)。业务用户改用两种方式:① 引导后手工执行 SQL(部署篇 4.7 节实测 CREATE ROLE admin ... → CREATE ROLE);② 编写 post_bootstrap 脚本由 Patroni 在引导收尾时执行。

5.6 postgresql 段:节点本地实例管理

postgresql:
  listen: 0.0.0.0:5432                # PG 监听(PG12+ 无需设置 port 参数,由 listen 拆分)
  connect_address: 10.89.60.11:5432   # 本节点 PG 对外宣告地址(主库身份信息)
  data_dir: /var/lib/postgresql/17/pgdemo   # 数据目录,Patroni 全权管理
  bin_dir: /usr/lib/postgresql/17/bin       # PG 可执行文件目录(pg_ctl/pg_rewind/pg_basebackup)
  # config_dir: /etc/postgresql/17/pgdemo   # 可选:postgresql.conf 外置目录;不设则放 data_dir
  parameters:
    unix_socket_directories: /var/run/postgresql   # 本地参数(仅本节点生效,不属于 DCS)
  authentication:
    superuser:
      username: postgres
      password: q1w2e3r4
    replication:
      username: replicator
      password: q1w2e3r4
    # rewind:
    #   username: rewind_user          # 不设则自动复用 superuser 凭据执行 pg_rewind
  # callbacks:                        # 角色变化回调脚本(on_start/on_stop/on_restart/on_role_change)
  #   on_role_change: /etc/patroni/vip.sh
  # create_replica_methods:           # 自定义克隆通道(pgbackrest/wal_g/basebackup)

实测说明:

  • data_dir 必须指向一个不存在或为空的目录(首节点 initdb 创建;从节点由 pg_basebackup 填充);目录属主在 systemd User=postgres 下由 Patroni 以 postgres 身份创建。
  • bin_dir 建议显式写出(多版本共存时避免歧义);PGDG 安装的 17 版本路径即 /usr/lib/postgresql/17/bin。
  • authentication.replication 的用户密码在引导时自动创建(部署篇 4.7 节 pg_stat_replication 实测可见 usename=replicator 正常流复制)。
  • postgresql.parameters 里写在文件中的是本地域,写在 bootstrap.dcs.postgresql.parameters 里的是 DCS 动态域——同名时 DCS 域优先。改本地域参数用 patronictl reload <集群> <节点> 触发本节点重新加载,改 DCS 域用 edit-config 全集群生效。

5.7 tags 段:节点角色微调

tags:
  nofailover: false      # true=本节点永不参与选主(可作纯查询从库)
  noloadbalance: false   # true=HAProxy 健康检查 /replica 对本节点返回 503(下线读写流量)
  clonefrom: false       # true=新节点加入时优先从本节点克隆(指定备份源)
  nosync: false          # true=同步复制模式下本节点不被选为 sync standby

实测说明:四个开关都是本节点属性,改动写回文件后 patronictl reload 即生效(无需重启进程)。典型用法:把一台慢盘节点设 nofailover: true 防止被提升;维护前临时 noloadbalance: true 摘流量。

5.8 高级段速览

配置段用途最小示例
synchronous_mode: true(置于 bootstrap.dcs)同步复制,故障转移零数据丢失(README 明示支持),synchronous_mode_strict 收紧写可用性synchronous_mode: true
watchdogLinux softdog 看门狗:失联主库被内核强杀,防脑裂双写watchdog: {mode: required, device: /dev/watchdog, safety_margin: 5}
standby_cluster级联灾备:整套集群跟随上游集群异步复制standby_cluster: {host: 上游主IP, port: 5432, primary_slot_name: pgdemo}
citus3.0+ 支持 Citus 分布式集群协调(README 明示)citus: {group: 0}
sslREST API 双向 TLSssl: {certfile: ..., keyfile: ...}
bootstrap.dcs.postgresql.parameters 追加生产常见追加:max_connections/shared_buffers/effective_cache_size/work_mem 等见第六章模板

六、生产环境推荐配置模板

基线假设:16GB 内存 / 512GB SSD / 8 vCPU / OLTP 读写混合负载的单节点。以下模板展示在部署篇 4.5 节骨架上叠加生产参数的关键增量(完整骨架见部署篇,此处不重复公共段)。

# === 在 bootstrap.dcs.postgresql.parameters 中追加(DCS 动态域,全集群生效)===
#      shared_buffers: '4GB'              # 25% 内存
#      effective_cache_size: '12GB'       # 操作系统缓存预算,约 75% 内存
#      work_mem: '32MB'                   # OLTP 混合负载基线,复杂排序多的业务再上调
#      maintenance_work_mem: '1GB'
#      max_connections: 200               # 配合 PgBouncer 使用,本值给直连预算
#      max_wal_size: '8GB'                # SSD 上放宽以减少 checkpoint 抖动
#      checkpoint_completion_target: 0.9
#      wal_compression: 'on'
#      log_min_duration_statement: 1000   # 慢 SQL 记录阈值 ms
#      autovacuum_max_workers: 4
#      autovacuum_vacuum_scale_factor: 0.05
#      track_io_timing: 'on'

# === 节点本地建议 ===
#   systemd 单元追加:
#     Environment=MALLOC_ARENA_MAX=1      # 官方 README 建议,规避 Python 3.11+ 内存池膨胀
#   同步复制零丢失(可接受写入延迟时):
#     bootstrap.dcs 下追加 synchronous_mode: true
#   维护通道加固:
#     restapi 开启 authentication 或 ssl

参数落地方式:DCS 域参数用 edit-config 全集群下发(3.2 节方法),本地域参数逐节点改文件后 patronictl reload。修改涉及重启的参数时排入维护窗口(3.3 节 pending restart 流程)。

七、常见问题(FAQ)

Q1:改了 patroni.yml 里的 bootstrap.dcs 却不生效?

bootstrap.dcs 只在集群首次引导时作为初始值写入 DCS;之后动态配置的权威数据在 etcd。生效路径只有两条:patronictl edit-config(3.2 节)或 curl -X PATCH .../config(REST,报文格式即 3.1 节 /config 的 JSON)。

Q2:patronictl list 出现 Pending restart 星号,怎么消除?

见 3.3 节:这是「改了需重启参数」的正常状态。先 patronictl reload 确认配置分发,再在维护窗口 patronictl restart pgdemo <节点> --force 重启对应节点进程。多节点需逐台重启(先从后主)。

Q3:DCS 参数改动会不会导致主从切换?

不会。edit-config 只重载配置;只有改动触发重启的参数且你主动执行 restart 时才会短暂重启 PG 实例。实测 3.2 节修改 max_wal_senders 过程中集群角色稳定(Leader/Replica 全程不变)。

Q4:bootstrap.users 为什么不生效?

4.0 起已移除(部署篇 FAQ 4 实测日志)。用 SQL 手工创建或 bootstrap.post_bootstrap 脚本。

Q5:python 3.11+ 上 Patroni REST API 假死?

官方 README「Memory issue on Python 3.11+」章节(2026-10-20 实查)记载:vm.overcommit_memory=2 等严格内存限制下 Python 3.11+ 新建线程可能无限挂起(CPython issue #140746)。处置:升级至 4.1.1+(本篇 4.1.5 已含缓解)、systemd 单元设置 MALLOC_ARENA_MAX=1、必要时调低 thread_stack_size(默认 512kB)。实测环境 Python 3.10.12 未复现。

Q6:pg_hba 改动会影响业务连接吗?

DCS 域 pg_hba 通过 edit-config 全集群下发后 Patroni 自动 reload 生效,注意先加后删(先下发放行新规则的版本,确认业务正常后再移除旧规则),避免把自己锁在外面。部署篇实测配置即含业务网段(10.89.60.0/24)与本机(127.0.0.1/32、::1/128)两类条目。

Q7:etcd3.hosts 只写一台可以吗?

技术上可行但不建议:该 etcd 宕机时 Patroni 将无法续约,可能触发整集群误判。务必写全 DCS 全部成员(5.3 节实测配置三台全列)。

八、参考链接