news 2026/4/23 10:23:07

PostgreSQL:主备切换(Failover),手动与自动切换演练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PostgreSQL:主备切换(Failover),手动与自动切换演练

文章目录

    • 一、基本概念与前提
      • 1.1 什么是 Failover?
      • 1.2 流复制基础
      • 1.3 切换类型
    • 二、手动 Failover 演练
      • 2.1 演练目标
      • 2.2 环境信息
      • 2.3 步骤 1:确认当前状态
      • 2.4 步骤 2:模拟主库故障
      • 2.5 步骤 3:在备库执行提升(Promote)
        • 方法一:使用 pg_ctl promote(推荐)
        • 方法二:创建 trigger 文件(适用于 PG 12+)
      • 2.6 步骤 4:验证新主库
      • 2.7 步骤 5:更新应用连接配置
      • 2.8 步骤 6:原主库恢复后重新加入(可选)
        • 方案 A:使用 pg_basebackup 重新初始化(简单可靠)
        • 方案 B:使用 pg_rewind(保留本地数据,更快)
    • 三、自动 Failover 演练(基于 Patroni)
      • 3.1 架构说明
      • 3.2 环境准备
      • 3.3 配置 etcd(192.168.1.12)
      • 3.4 配置 Patroni(node1 和 node2)
      • 3.5 启动 Patroni
      • 3.6 自动 Failover 演练
    • 四、关键配置对比
    • 五、注意事项与最佳实践
      • 5.1 避免脑裂(Split-Brain)
      • 5.2 复制延迟处理
      • 5.3 应用连接管理
      • 5.4 日志与监控
      • 5.5 测试建议

PostgreSQL 主备切换(Failover)是高可用架构中的关键操作,指在主库(Primary)发生故障时,将备库(Standby)提升为新的主库,以恢复数据库服务。根据实现方式不同,可分为手动切换自动切换。本文将从原理、准备、演练步骤、验证方法到注意事项,进行详细解析。


一、基本概念与前提

1.1 什么是 Failover?

Failover 是指当主库因硬件故障、网络中断、进程崩溃等原因不可用时,系统将写入流量切换至一个健康的备库,使其成为新的主库,从而保证业务连续性。

1.2 流复制基础

本文假设已搭建好基于物理流复制(Streaming Replication)的一主一备集群,且满足以下条件:

  • 主备 PostgreSQL 版本一致;
  • 已配置 WAL 流复制(wal_level = replica);
  • 备库处于hot_standby = on状态;
  • 网络互通,时间同步(NTP);
  • 使用操作系统用户postgres管理数据库。

若尚未搭建流复制集群,请先参考《PostgreSQL:万字详解如何搭建流复制集群》。

1.3 切换类型

类型触发方式是否需人工干预适用场景
手动 FailoverDBA 执行命令测试、可控维护、无 HA 工具环境
自动 FailoverHA 工具(如 Patroni、repmgr)检测并执行生产高可用环境

二、手动 Failover 演练

2.1 演练目标

  • 模拟主库宕机;
  • 手动将备库提升为主库;
  • 验证新主库可读写;
  • (可选)原主库恢复后重新加入集群作为新备库。

2.2 环境信息

节点IP角色数据目录
node1192.168.1.10Primary/var/lib/pgsql/14/data
node2192.168.1.11Standby/var/lib/pgsql/14/data

2.3 步骤 1:确认当前状态

在主库(node1)查看复制状态:

SELECT*FROMpg_stat_replication;-- 应看到 node2 的连接,state = streaming

在备库(node2)确认处于恢复模式:

SELECTpg_is_in_recovery();-- 返回 trueSHOWhot_standby;-- on

2.4 步骤 2:模拟主库故障

在 node1 上停止 PostgreSQL 服务:

sudosystemctl stop postgresql-14

或直接 kill 进程(更极端):

sudopkill-f postgres

此时应用连接主库将失败,需切换至备库。

2.5 步骤 3:在备库执行提升(Promote)

登录 node2,执行提升命令:

方法一:使用 pg_ctl promote(推荐)
sudo-u postgres pg_ctl promote -D /var/lib/pgsql/14/data

输出示例:

server promoting
方法二:创建 trigger 文件(适用于 PG 12+)

若在postgresql.conf中配置了promote_trigger_file,可创建该文件触发提升:

# postgresql.conf promote_trigger_file = '/tmp/promote.trigger'

然后:

sudo-u postgrestouch/tmp/promote.trigger

若未配置,则默认不启用此方式。

2.6 步骤 4:验证新主库

在 node2 上执行:

SELECTpg_is_in_recovery();-- 应返回 false

尝试写入数据:

CREATETABLEtest_failover(idint);INSERTINTOtest_failoverVALUES(1);SELECT*FROMtest_failover;-- 成功返回

说明 node2 已成功晋升为主库。

2.7 步骤 5:更新应用连接配置

将应用程序的数据库连接地址从192.168.1.10改为192.168.1.11,重启应用服务。

在生产中,通常通过 VIP(虚拟 IP)、DNS 或中间件(如 PgBouncer + HAProxy)实现透明切换。

2.8 步骤 6:原主库恢复后重新加入(可选)

原主库(node1)修复后,不能直接启动作为主库(会导致脑裂)。需将其重建为新备库。

方案 A:使用 pg_basebackup 重新初始化(简单可靠)
  1. 停止 node1 上的 PostgreSQL(若已启动):

    sudosystemctl stop postgresql-14
  2. 清空数据目录:

    sudorm-rf /var/lib/pgsql/14/data/*
  3. 从新主库(node2)拉取基础备份:

    sudo-u postgres pg_basebackup\-h192.168.1.11\-U repuser\-D /var/lib/pgsql/14/data\-P -v -R -X stream
  4. 启动 node1:

    sudosystemctl start postgresql-14
  5. 验证:

    SELECTpg_is_in_recovery();-- true
方案 B:使用 pg_rewind(保留本地数据,更快)

前提:原主库启用了data checksumswal_log_hints = on

  1. 在 node1 上安装 pg_rewind(通常随 PostgreSQL 一起安装)。

  2. 执行:

    sudo-u postgres pg_rewind\--target-pgdata=/var/lib/pgsql/14/data\--source-server="host=192.168.1.11 port=5432 user=repuser password=StrongPass123!"
  3. 创建 standby.signal:

    sudo-u postgrestouch/var/lib/pgsql/14/data/standby.signal
  4. 启动服务。

pg_rewind 优势:无需全量拷贝,仅同步差异页,速度快。


三、自动 Failover 演练(基于 Patroni)

手动切换适用于测试或小规模环境,但生产环境需自动化。Patroni 是目前最流行的 PostgreSQL HA 解决方案,基于分布式协调器(如 etcd、Consul、ZooKeeper)实现自动选主。

3.1 架构说明

  • Patroni:运行在每个 PostgreSQL 节点上的守护进程,管理实例启停、角色切换。
  • etcd:分布式键值存储,用于存储集群状态、选举 Leader。
  • VIP / DNS / Load Balancer:对外提供统一入口。

3.2 环境准备

新增一台服务器部署 etcd(IP: 192.168.1.12)。

在 node1 和 node2 安装 Patroni:

pip3installpatroni[etcd]

3.3 配置 etcd(192.168.1.12)

# /etc/etcd/etcd.conf.ymlname:etcd1data-dir:/var/lib/etcdlisten-client-urls:http://0.0.0.0:2379advertise-client-urls:http://192.168.1.12:2379listen-peer-urls:http://localhost:2380initial-advertise-peer-urls:http://localhost:2380initial-cluster:etcd1=http://localhost:2380initial-cluster-state:new

启动 etcd:

etcd --config-file /etc/etcd/etcd.conf.yml

3.4 配置 Patroni(node1 和 node2)

node1 的 patroni.yml:

scope:pg-clusternamespace:/service/name:pg-node1restapi:listen:192.168.1.10:8008connect_address:192.168.1.10:8008etcd:hosts:192.168.1.12:2379bootstrap:dcs:ttl:30loop_wait:10retry_timeout:10maximum_lag_on_failover:1048576postgresql:use_pg_rewind:trueuse_slots:trueparameters:wal_level:replicahot_standby:"on"max_wal_senders:10wal_keep_size:1GBarchive_mode:"off"initdb:-encoding:UTF8-data-checksumsusers:admin:password:admin123options:-createrole-createdbpostgresql:listen:192.168.1.10:5432connect_address:192.168.1.10:5432data_dir:/var/lib/pgsql/14/databin_dir:/usr/pgsql-14/binauthentication:replication:username:repuserpassword:StrongPass123!superuser:username:postgrespassword:postgres123!parameters:unix_socket_directories:'/tmp'tags:nofailover:falsenoloadbalance:false

node2 的 patroni.yml:

  • 修改name: pg-node2
  • 修改listenconnect_address192.168.1.11

注意:首次启动时,Patroni 会自动初始化集群(initdb),若已有数据,需注释initdb部分,并确保数据目录为空或已由 Patroni 管理。

3.5 启动 Patroni

在 node1 和 node2 分别启动:

patroni patroni.yml

Patroni 会自动选举一个主库(通常是先启动的节点)。

查看集群状态:

curlhttp://192.168.1.10:8008/cluster# 或patronictl -c patroni.yml list

输出示例:

+ Cluster: pg-cluster (7073733813877921290) -+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | +-----------+----------------+---------+---------+----+-----------+ | pg-node1 | 192.168.1.10 | Leader | running | 1 | 0 | | pg-node2 | 192.168.1.11 | Replica | running | 1 | 0 | +-----------+----------------+---------+---------+----+-----------+

3.6 自动 Failover 演练

  1. 模拟主库宕机:在 node1 上 kill Patroni 进程:

    pkill-f patroni
  2. 等待自动切换

    • etcd 在 TTL(30秒)内未收到心跳;
    • Patroni 在 node2 上检测到主库失联;
    • 触发选举,node2 自动 promote 为主库。
  3. 验证

    patronictl -c patroni.yml list

    输出应显示pg-node2为 Leader。

  4. 应用连接:若配置了 HAProxy,流量自动切至新主库,应用无感知。

  5. 恢复 node1

    • 重启 Patroni:
      patroni patroni.yml
    • Patroni 自动将其注册为 Replica,并通过 pg_rewind 或 basebackup 同步数据。

Patroni 默认启用use_pg_rewind: true,因此恢复速度快。


四、关键配置对比

功能手动切换Patroni 自动切换
故障检测人工判断心跳 + TTL 自动检测
提升操作手动执行 promote自动执行
脑裂防护依赖人工通过 DCS 锁机制避免
原主恢复需手动重建自动 rejoin
复制槽管理手动自动创建/删除
API 支持提供 REST API(8008端口)

五、注意事项与最佳实践

5.1 避免脑裂(Split-Brain)

  • 绝不允许两个节点同时作为主库接受写入。
  • 手动切换前务必确认原主库已彻底停止。
  • 自动切换必须依赖可靠的 DCS(如 etcd)进行仲裁。

5.2 复制延迟处理

  • 设置maximum_lag_on_failover(Patroni)防止提升严重滞后的备库。
  • 监控pg_stat_replication中的write_lsnflush_lsnreplay_lsn

5.3 应用连接管理

  • 使用连接池(PgBouncer) + 负载均衡(HAProxy) + 健康检查。
  • HAProxy 配置示例:
    backend pg_backend option httpchk http-check expect status 200 server pg1 192.168.1.10:5432 check port 8008 server pg2 192.168.1.11:5432 check port 8008
    Patroni 的 8008 端口提供/primary/replica等健康检查接口。

5.4 日志与监控

  • 记录所有 promote 操作日志;
  • 使用 Prometheus + Exporter 监控复制延迟、连接数等;
  • 设置告警(如主库宕机、延迟 > 100MB)。

5.5 测试建议

  • 定期进行 Failover 演练(季度);
  • 演练后验证数据一致性;
  • 测试“主库短暂闪断后恢复”的场景(是否误切换)。

总结:PostgreSQL 主备切换是保障数据库高可用的核心能力:

  • 手动 Failover:适合学习、测试或无自动化工具的环境,操作直接但依赖人工,风险较高。
  • 自动 Failover(Patroni):生产首选,具备故障检测、自动选主、安全防护、快速恢复等能力。

无论采用哪种方式,都必须:

  1. 确保流复制正常;
  2. 防止脑裂;
  3. 验证数据一致性;
  4. 配合应用层实现无缝切换。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 15:34:43

Qwen-Image-2512小白指南:从零开始玩转AI绘画

Qwen-Image-2512小白指南:从零开始玩转AI绘画 你是不是也遇到过这样的烦恼?脑子里构思了一幅绝美的画面:“一只仙鹤在江南水乡的晨雾中展翅,远处是黛瓦白墙”,但用AI工具生成时,出来的效果却总是不对味——…

作者头像 李华
网站建设 2026/4/20 5:33:01

无需专业知识!CLAP音频分类控制台快速上手指南

无需专业知识!CLAP音频分类控制台快速上手指南 你是否遇到过这样的场景:手机里存了一段音频,却想不起来是什么内容;或者想快速从一堆音频文件中找出所有包含特定声音(比如狗叫、掌声)的片段?传…

作者头像 李华
网站建设 2026/4/18 11:01:49

AI原生应用领域多代理系统的最新研究进展

AI原生应用领域多代理系统的最新研究进展 关键词:多代理系统(MAS)、AI原生应用、智能协作、大语言模型(LLM)、分布式智能 摘要:本文聚焦AI原生应用中多代理系统(Multi-Agent System, MAS)的前沿进展,从基础概念到最新技术,用生活化案例拆解“多个智能体如何像人类团队…

作者头像 李华
网站建设 2026/4/17 7:40:45

文脉定序效果展示:科研基金申报指南与课题方向语义匹配案例

文脉定序效果展示:科研基金申报指南与课题方向语义匹配案例 1. 智能语义重排序系统介绍 「文脉定序」是一款专注于提升信息检索精度的AI重排序平台,搭载了行业顶尖的BGE语义模型,专门解决传统索引"搜得到但排不准"的痛点。这个系…

作者头像 李华
网站建设 2026/4/23 5:46:27

Qwen3-TTS声音设计技巧:如何描述才能生成理想语音

Qwen3-TTS声音设计技巧:如何描述才能生成理想语音 1. 了解Qwen3-TTS的声音设计能力 Qwen3-TTS是一个强大的端到端语音合成模型,支持10种语言:中文、英文、日语、韩语、德语、法语、俄语、葡萄牙语、西班牙语和意大利语。与其他语音合成工具…

作者头像 李华
网站建设 2026/4/23 10:08:20

基于Java+SpringBoot的小学数学错题管理及推荐系统(源码+lw+部署文档+讲解等)

课题介绍本课题旨在设计并实现一款基于JavaSpringBoot框架的小学数学错题管理及推荐系统,解决小学生错题整理繁琐、重复刷题低效、知识薄弱点难以定位,以及教师无法精准掌握学生错题情况、个性化辅导不足等痛点,适配小学生、教师及家长的错题…

作者头像 李华