Patroni 4.1.5 配置参数详解
patroni.yml 两配置域(本地 vs DCS 动态)边界、HA 三大节拍 ttl/loop_wait/retry_timeout 机制、edit-config/show-config/REST 修改通道全实测,附生产配置模板与 8 条 FAQ(16GB/SSD/OLTP 基线)。
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 |
| Patroni | 4.1.5(patroni --version 实测) |
| PostgreSQL | 17.11(PGDG) |
| DCS | etcd v3.5.21(三节点,etcd3 驱动段连接) |
| 配置文件 | 每节点 /etc/patroni/patroni.yml(属主 root,组 postgres,640) |
| 配置基线假设 | 本文生产模板按 16GB 内存 / 512GB SSD / 8 vCPU / OLTP 读写混合负载 的通用主机配置给出 |
| systemd | patroni.service(PATRONICTL_CONFIG_FILE=/etc/patroni/patroni.yml、MALLOC_ARENA_MAX=1) |
二、前置条件
- 已按部署篇完成 3 节点集群并处于健康态(
patronictl list显示 1 Leader + 2 Replica streaming)。 - 每节点
/etc/patroni/patroni.yml内容与部署篇 4.5 节一致;patronictl通过-c指定或经环境变量PATRONICTL_CONFIG_FILE定位该文件。 - 修改 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)会出现两条证据链(实测回显):
- 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
- 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.dcs | DCS(仅首次引导) | 动态配置初始值 |
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 实查)
etcd3extra 对应 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 行为的骨架,三者关系与失效判定:
| 参数 | 默认 | 实测取值 | 作用与影响 |
|---|---|---|---|
ttl | 30 | 30 | leader key 租约秒数。主库 Patroni 持续续约;ttl 秒内无法续约即判主库失联,触发选主。调小→切换更快但抖动误切风险高 |
loop_wait | 10 | 10 | 每个节点检查集群状态/应用配置的周期。动态配置、角色变化都要等 1 个周期生效;调小→响应快、DCS 压力大 |
retry_timeout | 10 | 10 | 单次对 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 填充);目录属主在 systemdUser=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 |
watchdog | Linux softdog 看门狗:失联主库被内核强杀,防脑裂双写 | watchdog: {mode: required, device: /dev/watchdog, safety_margin: 5} |
standby_cluster | 级联灾备:整套集群跟随上游集群异步复制 | standby_cluster: {host: 上游主IP, port: 5432, primary_slot_name: pgdemo} |
citus | 3.0+ 支持 Citus 分布式集群协调(README 明示) | citus: {group: 0} |
ssl | REST API 双向 TLS | ssl: {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 节实测配置三台全列)。
八、参考链接
- 动态配置官方文档:https://github.com/patroni/patroni/blob/master/docs/dynamic_configuration.rst
- 环境变量与 YAML 设置官方文档:https://github.com/patroni/patroni/blob/master/docs/yaml_configuration.rst
- 复制模式(同步/异步):https://github.com/patroni/patroni/blob/master/docs/replication_modes.rst
- watchdog 官方文档:https://github.com/patroni/patroni/blob/master/docs/watchdog.rst
- standby cluster 官方文档:https://github.com/patroni/patroni/blob/master/docs/standby_cluster.rst
- PostgreSQL 17 参数手册:https://www.postgresql.org/docs/17/runtime-config.html
- 本专栏配套:《Patroni 4.1.5 3 节点高可用集群部署指南》(本篇全部实测的部署载体)、《Patroni 4.1.5 常用 CLI 命令与工具详解》