pglookout 2.0.3 配置参数详解
逐项讲清 pglookout 2.0.3 配置文件(JSON)全部参数键的含义、默认值、生效方式与相互制约关系,含 SIGHUP 热加载、复制延迟告警文件触发与自动消除、阈值钳制、autofollow 模板校验等实测行为,已在 Ubuntu 24.04 + PostgreSQL 16.15 三节点集群实测通过。
pglookout 2.0.3 配置参数详解
目标:逐项讲清 pglookout 2.0.3 配置文件(JSON)全部参数键的含义、默认值、生效方式与相互制约关系,含 SIGHUP 热加载、复制延迟告警文件触发与自动消除、阈值钳制、autofollow 模板校验等实测行为,已在 Ubuntu 24.04 + PostgreSQL 16.15 三节点集群实测通过。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 24.04 LTS(x86_64) |
| pglookout | 2.0.3(GitHub main 源码,venv 安装于 /opt/pglookout/venv,命令链接至 /usr/local/bin) |
| PostgreSQL | 16.15(Ubuntu 16.15-0ubuntu0.24.04.1) |
| 配置文件 | /etc/pglookout/pglookout.json(每节点一份,位置参数传入) |
| 状态文件 | /var/run/pglookout/pglookout_state.json(json_state_file_path) |
| 告警目录 | /var/run/pglookout(alert_file_dir) |
| HTTP 状态服务 | 每节点默认监听 15000 端口 |
| 集群拓扑 | 主 p1(10.89.60.11)/ 备 s1(10.89.60.12)/ 观察 obs1(10.89.60.13) |
| 监控账号 | pglookout(密码 q1w2e3r4,需 pg_monitor 角色 + pg_read_binary_file 授权) |
| 复制账号 | replicator(密码 q1w2e3r4,REPLICATION 属性) |
集群部署过程见 《pglookout 2.0.3 Docker Compose 部署指南》;组件定位与选型见 《pglookout 介绍与选型指南》。
二、前置条件
2.1 已部署三节点集群
pglookout 的配置必须放在已有可连接的 PostgreSQL 集群之上:主备已开流复制(wal_level=replica、hot_standby=on),监控角色已授权。授权基线(主库上执行,缺一则状态轮询持续报 InsufficientPrivilege,见 7.6):
CREATE ROLE pglookout LOGIN PASSWORD 'q1w2e3r4';
GRANT pg_monitor TO pglookout;
GRANT EXECUTE ON FUNCTION pg_read_binary_file(text) TO pglookout;
GRANT EXECUTE ON FUNCTION pg_read_binary_file(text, bigint, bigint) TO pglookout;
GRANT EXECUTE ON FUNCTION pg_read_binary_file(text, bigint, bigint, boolean) TO pglookout;
GRANT EXECUTE ON FUNCTION pg_read_binary_file(text, boolean) TO pglookout;
2.2 确认程序与配置文件可用
pglookout --version
2.0.3
python3 -m json.tool /etc/pglookout/pglookout.json > /dev/null && echo "JSON OK"
JSON OK
💡 说明:pglookout 没有「打印当前生效配置」的子命令,
pglookout的唯一位置参数就是配置文件路径;核对参数以文件内容 + 运行日志为准(见「三、参数查看与修改方式」)。
三、参数查看与修改方式
3.1 查看
配置文件即全部生效参数(未出现的键走内置默认值):
cat /etc/pglookout/pglookout.json
主节点实测回显:
{
"own_db": "p1",
"remote_conns": {
"p1": "host=10.89.60.11 dbname=postgres user=pglookout password=q1w2e3r4",
"s1": "host=10.89.60.12 dbname=postgres user=pglookout password=q1w2e3r4"
},
"observers": {
"obs1": "http://10.89.60.13:15000"
},
"http_address": "0.0.0.0",
"http_port": 15000,
"db_poll_interval": 5.0,
"replication_state_check_interval": 10.0,
"warning_replication_time_lag": 30.0,
"max_failover_replication_time_lag": 120.0,
"failover_command": "/opt/pglookout/failover.sh",
"failover_on_disconnect": true,
"known_gone_nodes": [],
"never_promote_these_nodes": [],
"maintenance_mode_file": "/tmp/pglookout_maintenance_mode_file",
"json_state_file_path": "/var/run/pglookout/pglookout_state.json",
"alert_file_dir": "/var/run/pglookout",
"log_level": "INFO",
"syslog": false,
"autofollow": false
}
运行期生效值可用状态文件交叉核对(current_master、各节点采样):
python3 -c "import json; d=json.load(open('/var/run/pglookout/pglookout_state.json')); print('current_master:', d['current_master'])"
current_master: p1
3.2 修改:SIGHUP 热加载(推荐)
编辑 /etc/pglookout/pglookout.json 后向进程发 SIGHUP,无需重启:
kill -HUP $(pidof pglookout)
log_level 为 DEBUG 时实测日志(节选):
2026-11-01 09:21:12,278 pglookout MainThread DEBUG Applying configuration version 5
2026-11-01 09:21:16,066 pglookout MainThread DEBUG Requesting config re-load (signal: 1, frame: <frame at 0x716f75b2e260, file '/usr/lib/python3.12/threading.py', line 359, code wait>)
INFO 级下热加载过程只露出决策类日志,实测(把 warning_replication_time_lag 临时改为 130.0 触发阈值钳制告警):
2026-11-01 09:16:32,248 pglookout MainThread WARNING Replication lag warning boundary (130.0) is not lower than its failover timeout (120.0)
2026-11-01 09:16:32,248 pglookout MainThread WARNING Replication lag warning boundary set to 120.0
2026-11-01 09:16:32,250 pglookout MainThread INFO Immediate failover check completed
热加载语义要点:
- 信号处理只置「待重载」标志,实际重读发生在下一个决策周期(
replication_state_check_interval)边界,故日志时间戳比kill -HUP晚 0~10 秒属正常。 - 重载会完整重算派生值(阈值钳制、
failover_command拆分、autofollow 模板解析)并立即做一次故障转移检查(Immediate failover check completed)。 remote_conns变化时监控线程自动清理旧连接、新建连接;HTTP 服务(http_address/http_port)不会随热加载重新绑定,改监听地址需重启进程。
3.3 修改:重启进程
官方推荐 systemd 托管(systemctl enable --now pglookout.service),改监听地址、换 venv 依赖等场景用:
systemctl restart pglookout
⚠️ 注意:本文验证环境无 systemd,重启路径以进程管理器(supervisord 等)等价执行;参数解析行为(3.2/3.4 的日志)在启动路径上完全相同(load_config() 同一入口)。
3.4 验证修改生效
三处交叉验证:
# 1) 决策日志(阈值类改动看 WARNING/INFO 行)
tail -20 /var/log/postgresql/pglookout.log # 或 journalctl -u pglookout -n 20
# 2) 状态文件时间戳持续刷新(5s 轮询 + 10s 决策周期)
stat -c '%y' /var/run/pglookout/pglookout_state.json
# 3) 告警目录(延迟类阈值改动观察 replication_delay_warning 出现/消失)
ls /var/run/pglookout/
四、参数总览
全量配置键与内置默认值(与官方 README「Configuration keys」逐项核对,并经源码 load_config() 验证):
| 参数键 | 默认值 | 一句话说明 |
|---|---|---|
own_db | 无 | 本节点在 remote_conns 中的键名;空串=纯观察节点 |
remote_conns | {} | 集群全部 DB 节点的 libpq 连接串(含自己) |
observers | {} | 其他观察节点的 HTTP 视点地址表 |
db_poll_interval | 5.0 | 轮询各 DB 节点状态的秒数 |
replication_state_check_interval | 10.0 | 故障转移决策周期秒数 |
warning_replication_time_lag | 30.0 | 复制延迟告警阈值(秒),超过即写告警文件 |
max_failover_replication_time_lag | 120.0 | 复制延迟故障转移阈值(秒),超过才允许提主 |
failover_command | "" | 判定需要故障转移时执行的外部脚本 |
failover_on_disconnect | true | 主库连接丢失是否直接触发故障转移决策 |
failover_sleep_time | 0.0 | 执行 failover_command 后的静默秒数 |
failover_priorities | {} | 多个候选备库延迟持平时的提升优先级表 |
over_warning_limit_command | null | 首次越过 warning 阈值时执行的外部命令 |
known_gone_nodes | [] | 已确认退出集群的节点名单(避免决策等待) |
never_promote_these_nodes | [] | 永不提升为主要的节点名单 |
maintenance_mode_file | /tmp/pglookout_maintenance_mode_file | 该文件存在时本节点不参与被提升 |
missing_master_from_config_timeout | 15 | 主库被移出配置后,等待多久按失联做故障转移 |
autofollow | false | 备节点是否自动维护 primary_conninfo 跟随新主 |
primary_conninfo_template | 无 | autofollow 使用的 conninfo 模板(key=value 串) |
pg_data_directory | /var/lib/pgsql/data | autofollow 需要写入的本地 PGDATA |
pg_start_command | "" | autofollow 重启本地 PG 的启动命令 |
pg_stop_command | "" | autofollow 重启本地 PG 的停止命令 |
json_state_file_path | /tmp/pglookout_state.json | JSON 状态文件路径 |
alert_file_dir | os.getcwd() | 告警文件目录 |
http_address | "" | 状态 API 监听地址(默认全接口) |
http_port | 15000 | 状态 API 监听端口 |
poll_observers_on_warning_only | false | 仅在延迟越过 warning 阈值时才轮询观察节点 |
log_level | "INFO" | 日志级别(DEBUG/INFO/WARNING/…) |
syslog | false | 是否同时输出 syslog |
syslog_address | /dev/log | syslog socket 地址(需 syslog: true) |
syslog_facility | local2 | syslog facility(需 syslog: true) |
statsd | 禁用 | StatsD/Telegraf 指标推送 {host, port, tags} |
cluster_monitor_health_timeout_seconds | 2×replication_state_check_interval | 采集线程超时计数阈值(配合 statsd) |
💡 说明:JSON 里没写的键一律取上表默认值;
alert_file_dir默认是进程工作目录、json_state_file_path默认在/tmp,生产务必显式改到持久且监控可见的目录(本文用/var/run/pglookout)。
五、核心参数分类详解
5.1 节点身份与集群拓扑(own_db / remote_conns / observers)
own_db:本节点在remote_conns表中的键。DB 节点必须填自己的键(主填p1、备填s1),pglookout 据此判断「我是不是主」;空串""表示纯观察节点,不做任何提升动作。观察节点实测初始化日志:
2026-11-01 08:58:04,038 pglookout MainThread INFO PGLookout initialized, local hostname: 'pg-observer', own_db: '', cwd: '/'
remote_conns:所有 DB 节点(包括自己)的连接串,key 为实例名。主备两节点的remote_conns内容完全一致,只有own_db不同。连接串支持 key=value 与 URI 两种 libpq 形态;pglookout 全程异步连接并在会话内SET synchronous_commit = off,监控查询不会拖慢业务提交。实测连接日志:
2026-11-01 08:58:06,143 ClusterMonitor Thread-1 INFO Connecting to 'p1' (host=10.89.60.11 dbname=postgres user=pglookout; hidden password)
2026-11-01 08:58:06,150 ClusterMonitor Thread-1 INFO Connecting to 's1' (host=10.89.60.12 dbname=postgres user=pglookout; hidden password)
observers:观察节点的 HTTP 基地址表({"名字": "http://ip:15000"})。db 节点周期性抓观察节点的/state.json,把「第三方视点」并入主库判定,用于网络分区时避免自以为是;观察节点自身该表应为{}。实测一次跨视点判定:
2026-11-01 08:58:06,164 pglookout MainThread WARNING No knowledge on 's1' {'fetch_time': '...', 'connection': False} from observer: 'obs1' is in recovery
2026-11-01 08:58:06,164 pglookout MainThread INFO New master node detected: old: None new: 'p1': {...}
⚠️ 注意:
remote_conns中不要包含观察节点(它没有 DB);一个观察节点可同时观察多套集群,反之 db 节点的observers建议至少配 1 个,官方 README 明确推荐「至少一个外部观察节点提供附加视点」。
5.2 轮询与决策节奏(db_poll_interval / replication_state_check_interval / replication_catchup_timeout / missing_master_from_config_timeout / poll_observers_on_warning_only)
db_poll_interval(默认 5.0):状态采集线程轮询remote_conns各节点的间隔。采集字段为now()、pg_is_in_recovery()、pg_last_xact_replay_timestamp()、收发/回放 LSN、逻辑复制槽状态。replication_state_check_interval(默认 10.0):主循环做「是否该故障转移」决策的周期,也是 SIGHUP 重载的落拍间隔。调小加快反应、加大减轻查询压力;本文取默认 5.0/10.0。replication_catchup_timeout(默认 300.0):备节点启动后允许「追赶主库」的窗口期,窗口内且尚未追近到 warning 阈值以下时抑制延迟告警与指标(防恢复期误报,见 5.3 与 7.2)。missing_master_from_config_timeout(默认 15):曾见过的主库被从remote_conns移除并发 SIGHUP 后,等待多少秒按「主库消失」走故障转移。配合known_gone_nodes可做到受控下线不等待。poll_observers_on_warning_only(默认 false):true 时仅当本地判定延迟越过 warning 阈值才去抓观察节点视点,减少 HTTP 开销,代价是平时没有第三方视点缓存。
实测节奏(决策周期 10s 内状态文件持续被 5s 采集刷新):
stat -c '%y' /var/run/pglookout/pglookout_state.json
2026-11-01 09:19:07.534120418 +0000
5.3 复制延迟阈值与告警(warning_replication_time_lag / max_failover_replication_time_lag / over_warning_limit_command / failover_on_disconnect / failover_sleep_time)
pglookout 的延迟口径是 replication_time_lag = 主库时间 - 备库最后回放事务时间戳(秒),在备节点自己的 pglookout 上判定。
warning_replication_time_lag(默认 30.0):越过即创建alert_file_dir/replication_delay_warning空文件并打 WARNING;若配了over_warning_limit_command则执行一次。max_failover_replication_time_lag(默认 120.0):越过才进入「提升备库」决策,并写failover_has_happened告警文件。- 两阈值有硬钳制关系:
warning >= max_failover时重载即告警并把 warning 压到 max_failover(实测,见 3.2 回显)。 failover_on_disconnect(默认 true):主库连不上(而非仅延迟)时是否允许故障转移;false 时日志打Not considering failover, because it's not enabled by configuration。failover_sleep_time(默认 0.0):执行failover_command后额外 sleep,留给外部脚本收尾。
告警文件触发与自动消除实测:在备库冻结 WAL 回放制造真实延迟(SELECT pg_wal_replay_pause();),默认 30s 阈值下备节点 pglookout 日志:
2026-11-01 09:20:22,504 pglookout MainThread WARNING Replication time lag has grown to: 39.860445 which is over WARNING boundary: 30.0, False
2026-11-01 09:20:22,504 pglookout MainThread WARNING No over_warning_limit_command set
告警文件同步出现:
ls /var/run/pglookout/
pglookout_state.json
replication_delay_warning
恢复回放(SELECT pg_wal_replay_resume();)后,下一决策周期延迟回落,pglookout 静默删除告警文件(源码无删除日志,以目录为准):
ls /var/run/pglookout/
pglookout_state.json
💡 说明:这套「告警文件出现=异常、消失=恢复」的机制就是 pglookout 对外接监控系统的原生方式(Zabbix/ Nagios 均可直接盯文件存在性),
over_warning_limit_command则是文件机制之外的钩子。
5.4 故障转移动作与名单控制(failover_command / known_gone_nodes / never_promote_these_nodes / failover_priorities / maintenance_mode_file)
failover_command:决策认定「需要转移」后,在将被提升的备节点上执行的外部命令(源码按空白拆分为 argv 数组,不支持 shell 管道语法,复杂逻辑一律放进脚本)。本文指向/opt/pglookout/failover.sh,内部执行pg_ctl promote。known_gone_nodes:受控下线(如主库彻底报废后从配置删除)时把节点名列入,备节点无需等missing_master_from_config_timeout即可决策。never_promote_these_nodes:无论回放位点多靠前都不提升的名单(如日志盘小的备)。failover_priorities:多个候选备 LSN 持平时按表选主,缺省用remote_conns键名字典序保证各节点选出同一个目标。maintenance_mode_file:该路径文件存在时,本节点在故障转移决策中直接跳过(日志this node has an existing maintenance_mode_file: '/tmp/pglookout_maintenance_mode_file'),是计划内维护的标准闸门:维护前touch,维护后删除。
⚠️ 注意:pglookout 的 failover 只负责「提升 + 让其余备库跟随」,不含 fence 旧主。
failover_command脚本里应实现 STONITH(如pg_ctl stop -m immediate远程关停旧主),否则旧主复活会形成双主,pglookout 只能在其他节点写multiple_master_warning告警兜底。
5.5 autofollow 与恢复配置(autofollow / primary_conninfo_template / pg_data_directory / pg_start_command / pg_stop_command)
autofollow: true(仅备节点开启)后,pglookout 全权接管备库的「跟随谁」:
- 用
primary_conninfo_template(key=value conninfo 串)+ 当前主节点的 host/port 生成完整primary_conninfo,写入pg_data_directory下的postgresql.auto.conf;模板里自带的 host/dbname 会被忽略并替换。 - 主库切换后自动重写配置并按
pg_stop_command/pg_start_command重启本地实例完成跟随。 - 模板缺失或非法时降级关闭 autofollow(实测回显):
2026-11-01 09:21:31,730 pglookout MainThread ERROR Invalid or missing primary_conninfo_template; not enabling autofollow
KeyError: 'primary_conninfo_template'
备节点实测生效证据——postgresql.auto.conf 被 pglookout 自动重写(注意首行署名注释与末尾注入的 host):
# pglookout updated primary_conninfo for instance p1 at 2026-11-01T09:06:40.264477Z
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=replicator password=q1w2e3r4 application_name=pglookout-standby sslmode=disable host=10.89.60.11'
recovery_target_timeline = 'latest'
pg_data_directory:pglookout 进程必须对该目录可写(写postgresql.auto.conf;PG16 已无 recovery.conf,README 中该表述针对老版本)。Ubuntu 发行版布局为/var/lib/postgresql/16/main。pg_start_command/pg_stop_command:以 OS 用户权限执行的发行版原生命令,Ubuntu 实测用pg_ctlcluster 16 main start/pg_ctlcluster 16 main stop -m fast;RHEL 系对应systemctl start/stop postgresql-16。- 未开 autofollow 的集群里,这四个键完全不参与逻辑(本文主节点即
autofollow: false)。
💡 技术拓展:备库跟随关系的维护方式不止 autofollow——
方式 维护者 特点 手工 primary_conninfoDBA 切换后需逐台改配置重启 pglookout autofollowpglookout 自动重写 auto.conf 并重启实例,需启停命令三键 repmgr followrepmgr 自带拓扑库,另一套生态 PG 原生 restore_command+信号文件备份工具 仅恢复场景 本文选 autofollow,因其与 pglookout 决策同源、无额外元数据库。
5.6 状态文件与告警文件(json_state_file_path / alert_file_dir)
json_state_file_path:主循环每决策周期原子写(.tmp+ rename)一份全集群视点:
{
"db_nodes": { "s1": {...}, "p1": {...} },
"observer_nodes": { "obs1": {...} },
"current_master": "p1"
}
辅助命令 pglookout_current_master 读的就是「配置文件 → json_state_file_path → 状态文件」这条链:
pglookout_current_master /etc/pglookout/pglookout.json; echo "exit=$?"
p1
exit=0
源码规则:状态文件 mtime 距今超过 60 秒视为 pglookout 已死,命令退出码 -1 且不打印——监控脚本必须以退出码为准,不能只看 stdout。
alert_file_dir:已知会写入的告警文件全集:authentication_error(任一 remote_conns 密码认证失败)、replication_delay_warning(越过 warning 阈值)、multiple_master_warning(同现两个非恢复态主)、failover_has_happened(执行过故障转移)。目录需 pglookout 可写,默认os.getcwd()极易踩「进程工作目录不可写/不可预期」的坑,生产务必显式配置。
5.7 HTTP 状态服务(http_address / http_port)
每个 pglookout 进程(含观察节点)内嵌一个只读 WebServer,默认 15000 端口,仅两个有效端点:
curl -s http://127.0.0.1:15000/state.json | head -c 300
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:15000/check
实测:/state.json 返回本节点视点 JSON(200);POST /check 触发一次立即集群检查并回 204(无 body)。观察节点上验证:
204
⚠️ 注意:访问其他路径时服务端发 404 但实现上未调用
end_headers(),curl 表现为挂起后000(实测 quirk)——探活与采集只用上面两个端点;http_address改绑地址或端口需重启进程(SIGHUP 不重绑,见 3.2)。
5.8 日志与指标(log_level / syslog / statsd / cluster_monitor_health_timeout_seconds)
log_level:DEBUG会额外暴露采集/重载全过程(3.2 实测的Requesting config re-load、Applying configuration version即 DEBUG 行);INFO 保留决策与异常,WARNING 及以上只剩异常。排障时临时改 DEBUG + SIGHUP 即可生效(该键热加载生效点在 load_config 内setLevel)。syslog三键:syslog: true后另挂一个 SysLogHandler 到syslog_address(默认/dev/log)的syslog_facility(默认local2),与 stdout 双写。发行版 rsyslog 需配local2.*规则才会落盘。statsd:配{host, port, tags}后按 Telegraf 语法推送pg.replication_lag等 gauge;不配即禁用(默认)。cluster_monitor_health_timeout_seconds:采集线程连续两轮(默认2×replication_state_check_interval)未成功完成即累加 statsd 计数cluster_monitor_health_timeout,仅在启用 statsd 时有意义。
六、生产配置模板
适用场景:16GB 内存、NVMe SSD、OLTP 主备 + 独立观察节点三机部署(PG 16,Ubuntu 24.04,systemd 托管)。
主节点 /etc/pglookout/pglookout.json:
{
"own_db": "db1",
"remote_conns": {
"db1": "host=db1.example.net dbname=postgres user=pglookout password=${PGLOOKOUT_PW}",
"db2": "host=db2.example.net dbname=postgres user=pglookout password=${PGLOOKOUT_PW}"
},
"observers": {
"obs1": "http://obs1.example.net:15000"
},
"http_address": "0.0.0.0",
"http_port": 15000,
"db_poll_interval": 5.0,
"replication_state_check_interval": 10.0,
"warning_replication_time_lag": 10.0,
"max_failover_replication_time_lag": 60.0,
"failover_command": "/usr/local/bin/pglookout-failover.sh",
"failover_on_disconnect": true,
"known_gone_nodes": [],
"never_promote_these_nodes": [],
"maintenance_mode_file": "/var/run/pglookout/maintenance",
"json_state_file_path": "/var/run/pglookout/state.json",
"alert_file_dir": "/var/run/pglookout",
"log_level": "INFO",
"syslog": true,
"autofollow": false
}
备节点:同主节点,改 "own_db": "db2",并追加 autofollow 四键:
{
"autofollow": true,
"pg_data_directory": "/var/lib/postgresql/16/main",
"pg_start_command": "sudo /usr/bin/pg_ctlcluster 16 main start",
"pg_stop_command": "sudo /usr/bin/pg_ctlcluster 16 main stop -m fast",
"primary_conninfo_template": "user=replicator password=${REPLICATOR_PW} application_name=pglookout-db2 sslmode=require"
}
观察节点:
{
"own_db": "",
"remote_conns": {
"db1": "host=db1.example.net dbname=postgres user=pglookout password=${PGLOOKOUT_PW}",
"db2": "host=db2.example.net dbname=postgres user=pglookout password=${PGLOOKOUT_PW}"
},
"observers": {},
"http_address": "0.0.0.0",
"http_port": 15000,
"json_state_file_path": "/var/run/pglookout/state.json",
"alert_file_dir": "/var/run/pglookout",
"log_level": "INFO"
}
模板要点:
- 阈值收紧为 10s/60s(默认 30/120 对 OLTP 偏松),且保持 warning < max_failover 的钳制关系;
maintenance_mode_file挪进alert_file_dir同目录,便于运维一眼看全 pglookout 的文件面;- 生产密码不落文档:模板中
${PGLOOKOUT_PW}/${REPLICATOR_PW}由配置管理渲染注入(如 Ansible template 读取 Vault 值,或落地前export PGLOOKOUT_PW='<真实密码>'后用envsubst < pglookout.json.tpl > /etc/pglookout/pglookout.json生成),sslmode=require保护复制与监控连接; failover_command脚本必须包含 STONITH 旧主逻辑(见 5.4 注意);- systemd 单元示例(三节点相同):
[Unit]
Description=pglookout replication monitor
After=network-online.target postgresql.service
[Service]
ExecStart=/usr/local/bin/pglookout /etc/pglookout/pglookout.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
[Install]
WantedBy=multi-user.target
七、常见问题
7.1 warning 阈值大于等于 failover 阈值时配置「看似无效」
现象:设 warning_replication_time_lag: 130 后延迟 100s 也不告警。
定位:源码 load_config 强制 warning < max_failover,重载即钳制并告警(实测):
Replication lag warning boundary (130.0) is not lower than its failover timeout (120.0)
Replication lag warning boundary set to 120.0
解决:保持两阈值严格递增(如 10/60、30/120),以日志 WARNING 行为准。
7.2 把 warning 阈值调得比历史最小延迟还低,结果不告警
现象:备节点设 warning_replication_time_lag: 0.5 甚至 1.9,延迟文件始终不出现(实测两轮均未触发)。
定位:状态文件里除 replication_time_lag 外还有 min_replication_time_lag(启动以来最小延迟,实测 min: 0.192627)。源码 is_restoring_or_catching_up_normally() 在 min_replication_time_lag >= warning 时判定节点「仍在追赶」,整体抑制告警与指标——阈值低于历史最小延迟时永远满足该条件。
解决:warning 必须高于备库正常运行时的最小延迟观测值(看状态文件 min_replication_time_lag),制造确定性延迟可用 pg_wal_replay_pause()(见 5.3)。
7.3 配置文件 JSON 语法错误:进程直接退出
现象:改完配置重启,服务起不来(实测):
ERROR Invalid JSON config, exiting
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
EXIT=1
定位:load_config 捕获任何解析异常后 sys.exit(1),无回退旧配置逻辑。
解决:改配置先 python3 -m json.tool 校验再 SIGHUP/重启(见 2.2);systemd Restart=always 下坏配置会造成 crash-loop,务必用校验闸门。
7.4 SIGHUP 后似乎没反应
定位:重载在下一个决策周期边界才执行(3.2 要点 1),且 INFO 级下正常重载可能只有一行 Immediate failover check completed。
解决:临时 log_level: DEBUG + 再发一次 SIGHUP,看到 Requesting config re-load (signal: 1, ...) 即链路正常;若仍无,检查信号是否发给 pglookout 主进程本身(pidof pglookout),以及配置文件是否真的可读、JSON 是否合法(7.3)。
7.5 autofollow 开了但主备切换后备库没跟随
定位:三键不齐 autofollow 直接关闭(实测 Invalid or missing primary_conninfo_template; not enabling autofollow);另一常见原因是 pg_data_directory 不可写或 pg_start_command/pg_stop_command 权限不足。
解决:核对备节点配置含全部四键(5.5);以 postgres 用户实测启停命令可执行;确认 postgresql.auto.conf 出现 # pglookout updated primary_conninfo ... 署名注释。
7.6 主节点状态轮询持续 InsufficientPrivilege
现象:日志每轮出现:
InsufficientPrivilege (permission denied for function pg_read_binary_file)
状态文件里主节点 connection: false。
定位:采集逻辑复制槽状态时执行 pg_read_binary_file('pg_replslot/.../state'),即使 0 个逻辑槽也做函数 ACL 检查;仅 pg_monitor 角色不够。
解决:按 2.1 对 4 个重载签名逐一 GRANT EXECUTE。
7.7 pglookout_current_master 无输出、退出码 255
定位:辅助命令对状态文件 mtime 超 60 秒直接返回 -1(shell 显示 255)——pglookout 死了、或配置里 json_state_file_path 与实际写入路径不一致。
解决:systemctl status pglookout 确认进程;比对配置文件与 ls -l 状态文件时间戳。
八、参考链接
- 《pglookout 介绍与选型指南》(本专栏 A1 篇)
- 《pglookout 2.0.3 Docker Compose 部署指南》(本专栏 B2 篇)
- 官方 README「Configuration keys」(参数默认值权威来源):https://github.com/aiven/pglookout/blob/main/README.rst
- 源码
pglookout.pyload_config / 阈值钳制 / autofollow 校验:https://github.com/aiven/pglookout/blob/main/pglookout/pglookout.py - PostgreSQL 16 复制配置:https://www.postgresql.org/docs/16/runtime-config-replication.html