1. 当我们谈论故障转移时,究竟在讨论什么
双十一凌晨两点,电商系统的主数据库突然宕机。此时的数据库管理员有两种选择:要么摸黑登录服务器逐个执行命令(手动切换),要么让系统像自动驾驶汽车般自主接管(自动故障转移)。这就是PostgreSQL流复制环境下必须掌握的生存技能。
让我们通过真实的命令行示例,演示如何在这两种模式间游刃有余。本次技术栈限定为:PostgreSQL 14 + Patroni 2.1 + Ubuntu 20.04。
2. 手动故障转移的五指山
2.1 典型战场环境
$ tail -n 5 /var/log/postgresql/postgresql-14-main.log
FATAL: could not access file "pg_wal/0000000100000001000000FE": No such file or directory
PANIC: could not locate a valid checkpoint record
2.2 传统维修三板斧
# Step1 确认备库状态
$ psql -h standby1 -p 5432 -U replicator -c "SELECT pg_is_in_recovery();"
pg_is_in_recovery
-------------------
t
# Step2 提升备库为主(需要执行于备库服务器)
$ pg_ctl promote -D /var/lib/postgresql/14/main
waiting for server to promote.... done
# Step3 验证新主库状态
$ psql -h new_primary -p 5432 -U postgres -c "SELECT pg_is_in_recovery();"
pg_is_in_recovery
-------------------
f
# 注意:原主库恢复后需重新配置为备库
手动画重点⚠️:整个过程要求管理员对集群状态了如指掌,每次操作间隔都可能造成分钟级服务中断。就像开着老爷车换轮胎,技术简单但风险极大。
3. Patroni的自动化魔术
3.1 先来看看指挥官的装备
# /etc/patroni/config.yml 核心配置片段
restapi:
listen: 0.0.0.0:8008
connect_address: 192.168.1.101:8008
etcd:
host: 192.168.1.100:2379
bootstrap:
dcs:
ttl: 30
retry_timeout: 10
maximum_lag_on_failover: 1048576
initdb:
- encoding: UTF8
- data-checksums
postgresql:
name: node1
listen: 0.0.0.0:5432
connect_address: 192.168.1.101:5432
data_dir: /var/lib/postgresql/14/main
bin_dir: /usr/lib/postgresql/14/bin
pgpass: /tmp/pgpass
parameters:
max_connections: 100
shared_buffers: 2GB
3.2 自动换胎的真实表演
# 模拟主库断电(Ctrl+Alt+Del电源键)
$ patronictl -c /etc/patroni/config.yml list
+ Cluster: pg_cluster (7016878103969147211) ------+----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+--------+---------------+---------+---------+----+-----------+
| node1 | 192.168.1.101 | Leader | running | 5 | |
| node2 | 192.168.1.102 | Replica | running | 5 | 0 |
+--------+---------------+---------+---------+----+-----------+
# 等待20秒后再次查看
+ Cluster: pg_cluster (7016878103969147211) ------+----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+--------+---------------+---------+---------+----+-----------+
| node2 | 192.168.1.102 | Leader | running | 5 | |
| node1 | 192.168.1.101 | Replica | stopped | | unknown |
+--------+---------------+---------+---------+----+-----------+
技术亮点✨:当主库宕机时,Patroni通过ETCD选举立即触发故障转移,整个过程比手动操作快至少10倍。就像特斯拉的爆胎续跑功能,乘客甚至察觉不到异常。
4. 为什么你的选择很重要
4.1 应用场景对决
手动切换适用场景
- 开发环境故障演练
- 小型内部系统(可容忍分钟级中断)
- 需要严格审计操作记录的场景
Patroni自动切换适用场景
- 电商大促期间的核心交易库
- 金融行业实时交易系统
- 7x24小时运营的物联网平台
4.2 技术参数擂台
| 对比维度 | 手动切换 | Patroni自动切换 |
|---|---|---|
| 响应时间 | 3-15分钟 | 5-30秒 |
| 配置复杂度 | ★☆☆☆☆(简单) | ★★★★☆(需分布式协调服务) |
| 人工干预度 | 全程人工操作 | 仅需监控告警 |
| 数据一致性 | 可能丢失未同步事务 | 自动检测同步状态 |
| 故障恢复率 | 依赖人员技能 | 预设策略自动执行 |
5. 那些年我们踩过的坑
5.1 网络分裂陷阱
# 三节点集群遭遇网络分区
node1 (旧主) ---------×---------- node2
\
×---------------- node3
# Patroni的处理逻辑
1. 多数派节点(node2+node3)触发选举
2. node3被提升为新主
3. 网络恢复后node1自动降级为备库
实战经验💡:务必配置奇数个节点(推荐3或5个),避免脑裂问题。网络延时建议保持在3ms以内。
5.2 WAL归档的暗箭
-- 创建连续归档任务
ALTER SYSTEM SET archive_mode = on;
ALTER SYSTEM SET archive_command = 'gzip < %p > /archive/%f.gz';
警示牌🚧:自动故障转移绝不意味着可以忽视基础维护,建议每日检查归档目录空间使用率。
6. 技术选择的正确姿势
混合部署策略
在大型生产环境中,可以采用Patroni自动切换为主、手动切换为辅的模式。例如核心库使用Patroni集群,报表库采用手动切换。监控三板斧
- Patroni REST API状态监控
- pg_stat_replication同步延迟
- ETCD集群健康检查
定期灾难演练
推荐每月执行一次完整流程:
# 模拟主库宕机测试
$ patronictl remove pg_cluster --force
$ systemctl stop patroni
# 观察备库选举过程并记录时间
评论