数据库高可用集群管理运维后端【免费下载链接】patroniA template for PostgreSQL High Availability with Etcd, Consul, ZooKeeper, or Kubernetes项目地址https://gitcode.com/gh_mirrors/pa/patroni点击查看免费下载Patroni 提供了一套与 Pacemaker 维护模式maintenance mode等价的集群暂停Pause/恢复Resume机制在暂停状态下Patroni 会脱离正在运行的集群不再自动干预 PostgreSQL 实例状态同时继续把集群状态保留在 DCS分布式配置存储中。本文以 docs/pause.rst 为主线结合 patroni/ha.py、patroni/ctl.py、patroni/global_config.py 等源码实现系统讲解 Pause 模式的设计目标、暂停期间的精确行为边界以及通过patronictl pause/resume命令和 REST API 触发维护模式的具体操作帮助你在做大版本升级、崩溃恢复等非常规操作时安全地冻结自动故障转移。一、为什么需要 Pause 模式The goal在正常运行时Patroni 的主循环会持续监控集群状态并自动做出决策检测到主节点故障就触发故障转移、发现多余的 primary 就降级、发现副本掉线就尝试拉起等。但某些运维场景下这些自动化恰恰是灾难的源头大版本升级major version upgrades节点会被以 Patroni 无法理解的方式反复启停甚至某个节点可能被临时提升temporarily promoted崩溃恢复corruption recovery需要人工介入、手工操作 PostgreSQL此时自动故障转移会干扰人工流程其他对集群进行非常规操作uncommon activities的场景。这些操作违背了 Patroni 最基本的假设——整个集群同一时刻只能有一个 primary。如果 Patroni 此时仍按常规逻辑运行可能会把人工临时提升的节点重新降级或把刚停掉的节点强行拉起导致操作失败甚至数据损坏。因此 Patroni 需要一种能力临时脱离detach正在运行的集群不再改变 PostgreSQL 的状态但继续把集群状态保留在 DCS 中。这正是 Pause 模式的目标功能上等价于 Pacemaker 中的 maintenance mode。二、Pause 状态的存储与传播DCS 中的pause键Pause 状态是一个集群级全局配置存放在 DCS 的{namespace}/{cluster}/config键中而不是某个节点的本地配置。在源码中这一状态由GlobalConfig类管理见 patroni/global_config.pydef check_mode(self, mode: str) - bool: Checks whether the certain parameter is enabled. :param mode: parameter name, e.g. synchronous_mode, failsafe_mode, pause, check_timeline, and so on. return bool(parse_bool(self.__config.get(mode))) property def is_paused(self) - bool: True if cluster is in maintenance mode. return self.check_mode(pause)所有节点都会从 DCS 读取这份全局配置因此pause: true一旦写入 DCS整个集群的每个 Patroni 实例都会在下一个 HA 循环周期内感知并进入维护模式。这保证了暂停操作是集群级的而不是单节点的。三、Pause 模式下的行为边界The implementationPause 模式的核心承诺是Patroni 不改变 PostgreSQL 的状态。但不改变并不等于完全休眠——为了维持集群元数据的正确性Patroni 仍保留了少量必要动作。以下逐条说明暂停期间 Patroni 到底会做什么、不会做什么。3.1 仍然更新成员信息键member key对于每个节点即使处于暂停状态Patroni 依然会把当前集群信息更新到 DCS 的 member key 中。如果该成员节点上的 PostgreSQL 正在运行这会触发 Patroni 对该节点执行只读查询以采集最新状态。对应实现位于 patroni/ha.py 的update_lock流程中if self.is_paused(): data[pause] True ret self.dcs.touch_member(data)也就是说暂停期间成员的心跳与状态上报仍在继续DCS 中的集群视图成员列表、角色、时间线等保持新鲜这对后续恢复运维非常有价值。3.2 持有 leader lock 的 primary更新锁而不夺回锁对于持有 leader lock 的 PostgreSQL primaryPatroni 暂停期间只更新锁续租维持锁不过期。一个关键边界是如果持有 leader lock 的节点被手工降级demoted manually即它不再是 primaryPatroni 会直接释放该锁而不会把这个节点重新提升回去。这是防止人工降级又被自动提升循环的关键设计——暂停期间Patroni 尊重人工对节点角色的裁决绝不逆操作。对应逻辑可以在 patroni/ha.py 中看到暂停状态下节点只有在其 sysid 与集群initialize键匹配时才被认为是健康的从而不会因我是 primary 且集群无锁而自动抢锁。3.3 允许与禁止的操作清单暂停状态下Patroni 对人工操作的放行规则非常明确操作类型暂停期间是否允许说明手动非计划重启manual unscheduled restart✅ 允许不阻止人工重启节点手动非计划 failover / switchover✅ 允许见下方约束reinitialize✅ 允许允许重建副本计划内操作scheduled action❌ 禁止暂停期间不允许任何计划任务无指定候选节点的手动 switchover❌ 禁止必须显式指定切换目标其中手动 switchover 必须指定目标节点的约束在 patroni/api.py 中有明确实现if not data and config.is_paused and not candidate: data Switchover is possible only to a specific candidate in a paused state同样暂停状态下无法发起计划内scheduled重启见 patroni/api.pyif global_config.from_cluster(cluster).is_paused and schedule in request: self.write_response(status_code, Cant schedule restart in the paused state)这些限制的意图很清晰暂停模式是为了配合人工立即执行的非常规操作任何将来某个时刻自动执行的计划任务都被禁止避免与人工流程撞车。3.4 检测到并行 primary只告警不降级如果 Patroni 检测到集群中出现了多个 primary例如人工临时提升导致在正常情况下它会立即降级没有 leader lock 的那个 primary。但在暂停模式下Patroni 只发出 warning 日志不会降级没有 leader lock 的 primary。这是 Pause 模式不改变 PostgreSQL 状态承诺的直接体现人工临时提升的节点不会被自动拉回从而保护了正在进行的升级/恢复操作。3.5 没有 leader lock 时的处理规则暂停期间如果集群中不存在 leader lockPatroni 的行为取决于当前 primary 的情况存在一个正在运行的 primary该 primary 会获取 leader lock维持锁的归属存在多个 primary第一个成功获取 leader lock 的 primary 胜出没有任何 primaryPatroni不会尝试提升任何副本——正常模式下的自动提升逻辑在暂停期间被关闭。一个例外如果 leader lock 消失的原因是旧 primary 因手动提升请求manual promotion而自我降级那么只有该提升请求中指定的候选节点可以获取 leader lock。当新的 leader lock 被授予即手动提升副本成功后Patroni 会确保原来从旧 leader 流式复制的副本切换到新 leader 上继续复制——这是暂停模式下唯一被允许的自动纠偏动作目的是让集群尽快恢复一致。对应实现可参考 patroni/ha.py暂停且存在非计划 failover 时走manual_failover_process_no_leader()路径处理无 leader 场景且只有候选节点能胜出。3.6 停止行为双向不干预暂停模式对启停操作有两条对称的规则Postgres 被停止时Patroni 不尝试启动它——人工停掉的实例不会被自动拉起Patroni 被停止时它不尝试停止其管理的 Postgres 实例——Patroni 进程退出不会连带把 PostgreSQL 关掉。这两条保证了在升级/维护窗口内无论操作哪一层Patroni 进程层或 PostgreSQL 实例层都不会产生级联副作用。3.7 复制槽replication slots清理的豁免正常模式下Patroni 会清理那些既不代表其他集群成员、又不在 permanent slots 配置中的复制槽。但在暂停模式下Patroni 不会尝试移除任何复制槽即使它们不满足上述条件。这避免了维护窗口内槽位被意外删除导致副本断流。四、用户操作指南User guide4.1 使用patronictl pause/patronictl resume最常用的触发方式是patronictl命令。完整命令参考见 docs/patronictl.rst 中的patronictl pause与patronictl resume小节。patronictl pause将集群置入维护模式禁用自动故障转移pause [ CLUSTER_NAME ] [ --group CITUS_GROUP ] [ --wait ]参数说明参数含义CLUSTER_NAMEPatroni 集群名缺省时从配置文件的scope读取--group CITUS_GROUP仅暂停指定的 Citus group集群 ID缺省时从citus.group配置读取--wait阻塞等待所有 Patroni 成员都完成暂停后再返回控制权实际操作示例对应 docs/patronictl.rst$ patronictl -c postgres0.yml pause batman --wait pause request sent, waiting until it is recognized by all nodes Success: cluster management is pausedpatronictl resume让集群退出维护模式重新启用自动故障转移resume [ CLUSTER_NAME ] [ --group CITUS_GROUP ] [ --wait ]参数含义与pause完全对应。示例见 docs/patronictl.rst$ patronictl -c postgres0.yml resume batman --wait resume request sent, waiting until it is recognized by all nodes Success: cluster management is resumed命令的底层实现两个命令都最终调用 patroni/ctl.py 中的toggle_pause()。其工作流程为从 DCS 读取当前集群状态若global_config.from_cluster(cluster).is_paused已经等于目标状态直接抛错Cluster is already/not paused按leader 优先顺序遍历所有成员向每个成员发送PATCH /config请求载荷为{pause: paused or None}若指定了--wait则通过wait_until_pause_is_applied(dcs, paused, cluster)阻塞直到所有节点确认生效否则立即打印 Success请求失败的成员会被记录 warning 并跳过。4.2 通过 REST API 直接 PATCH除patronictl外也可以直接向任意成员节点的 REST API 发送PATCH请求目标键为{namespace}/{cluster}/config请求体为{pause: true} // 进入暂停 {pause: false} // 恢复运行 {pause: null} // 清空该字段恢复默认实际上patronictl pause/resume内部正是通过这个 API 实现的toggle_pause中request_patroni(member, patch, config, {pause: paused or None})因此两种方式效果完全一致。暂停状态下通过 REST API 获取集群信息时返回结果中会携带pause: True标记见 patroni/api.py同时 API 的存活检查liveness在暂停模式下更加宽容——即使心跳循环卡住也返回 200见 patroni/api.py# In maintenance mode (pause) we are fine if heartbeat loop stuck. status_code 200 if patroni.ha.is_paused() or patroni.next_run liveness_threshold time.monotonic() else 503五、暂停状态的观测5.1patronictl list中的状态列使用patronictl list查看集群时若集群处于暂停状态会在输出中体现Cluster is paused相关标记Cluster is paused状态仅在暂停且输出格式为pretty时显示参见 docs/patronictl.rst。5.2 Prometheus 指标patroni_is_pausedPatroni 的/metrics端点暴露了暂停状态的监控指标便于接入告警与可视化见 patroni/api.py# HELP patroni_is_paused Value is 1 if auto failover is disabled, 0 otherwise. # TYPE patroni_is_paused gauge patroni_is_paused{...} 1值为 1 表示自动故障转移当前被禁用即集群处于暂停状态。运维上可以基于该指标为集群意外处于维护模式过久配置告警避免维护窗口结束后忘记resume。六、典型使用场景与最佳实践综合以上行为边界Pause 模式的推荐使用流程如下进入维护模式执行patronictl -c postgres0.yml pause cluster --wait或 PATCH{pause: true}确认输出 Success: cluster management is paused执行非常规操作此时可以放心地停启节点、人工提升/降级节点、做崩溃恢复或大版本升级Patroni 不会自动干预即使出现并行 primary也只会告警不会降级恢复自动管理操作完成后执行patronictl -c postgres0.yml resume cluster --wait或 PATCH{pause: false}确认集群恢复自动故障转移能力。需要特别留意的实践要点计划内操作在暂停期间被禁止如果需要在维护窗口内做计划重启/计划切换应在进入暂停之前安排好或直接使用非计划的即时操作手动 switchover 必须显式指定候选节点暂停期间switchover不指定目标会直接报错这是设计使然复制槽不会被自动清理维护期间残留的失效槽位不会在暂停中被清除恢复运行后 Patroni 会按正常规则继续管理人工降级 leader 后锁会被释放如果人工把主节点降级了Patroni 不会把它再提升回来这与正常模式的行为有本质区别请勿在暂停期间期待任何自动提升除了手动提升请求指定候选的例外。七、小结Pause/Resume 模式是 Patroni 面向人工介入的非常规运维提供的核心安全机制其本质是一份精确的行为边界契约暂停期间 Patroni 维持 DCS 集群视图的活性member key、leader lock 续租尊重人工对节点角色的一切裁决禁用计划任务与自动提升同时通过告警而非降级来容忍并行 primary。理解并善用patronictl pause/resume与PATCH /config两种触发方式再结合patroni_is_paused指标做好监控兜底就能让大版本升级与崩溃恢复等高风险操作在受控、可观测的前提下安全完成。赞分享数据库高可用集群管理运维后端【免费下载链接】patroniA template for PostgreSQL High Availability with Etcd, Consul, ZooKeeper, or Kubernetes项目地址https://gitcode.com/gh_mirrors/pa/patroni点击查看免费下载相关推荐Ceph集群主机维护操作指南cephadm维护模式详解Ceph集群主机维护操作指南cephadm维护模式详解 前言 在Ceph分布式存储系统的日常运维中主机维护是一项常见但关键的操作。无论是硬件升级、系统补丁还存储分布式文件系统对象存储后端高可用scrcpy 录制3 条命令把手机录屏到电脑scrcpy 录制3 条命令把手机录屏到电脑 scrcpy 录制是把 Android 手机的画面和声音原样存到电脑上手机不用装任何录屏 App也不用担心音音视频LogDevice集群维护操作指南LogDevice集群维护操作指南 概述 LogDevice是一个高性能的分布式日志存储系统在生产环境中运行需要掌握集群维护的关键操作。本文将详细介绍LogD上一篇Bus Pirate固件完全指南从入门到精通的开源硬件调试工具下一篇pipreqs开发环境搭建终极指南Poetry与pyproject.toml快速配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考