外观
PostgreSQL 故障转移测试
故障转移测试是验证PostgreSQL高可用架构在主库故障时,能否自动或手动切换到备库,确保业务连续性的重要手段。测试主要包括手动故障转移测试、自动故障转移测试和半自动化故障转移测试,目标是验证故障转移机制的可靠性、测量故障转移时间、验证数据一致性、验证应用程序能否自动重连以及验证监控和告警是否正常。
测试准备工作
1. 环境准备
bash
# 检查主备状态
psql -h primary_host -U postgres -c "SELECT * FROM pg_stat_replication;"
psql -h standby_host -U postgres -c "SELECT * FROM pg_stat_wal_receiver;"
# 备份当前配置
pg_dumpall -h primary_host -U postgres -f pre_test_backup.sql
# 准备测试数据
psql -h primary_host -U postgres -c "CREATE DATABASE test_db;"
psql -h primary_host -U postgres -d test_db -c "CREATE TABLE test_table (id SERIAL PRIMARY KEY, data VARCHAR(100));"
psql -h primary_host -U postgres -d test_db -c "INSERT INTO test_table (data) VALUES ('test data');"2. 工具准备
- psql:PostgreSQL命令行工具
- pgbench:基准测试工具,用于模拟负载
- patronictl:Patroni集群管理工具(如果使用Patroni)
- HAProxy:负载均衡器(如果使用)
- 监控工具:Prometheus+Grafana、pgAdmin等
3. 测试计划
| 测试场景 | 测试步骤 | 预期结果 | 验证方法 |
|---|---|---|---|
| 主库崩溃 | 1. 终止主库进程 2. 执行故障转移 | 备库晋升为主库 数据无丢失 | 检查备库状态 验证测试数据 |
| 网络中断 | 1. 断开主库网络 2. 等待自动故障转移 | 备库晋升为主库 应用程序自动重连 | 检查集群状态 验证应用连接 |
| 存储故障 | 1. 模拟主库存储故障 2. 执行故障转移 | 备库晋升为主库 数据一致性 | 验证数据完整性 检查WAL位置 |
手动故障转移测试
1. 基于流复制的手动故障转移
bash
# 步骤1:在备库检查主备同步状态
psql -h standby_host -U postgres -c "SELECT * FROM pg_stat_wal_receiver;"
# 步骤2:在主库插入测试数据
psql -h primary_host -U postgres -d test_db -c "INSERT INTO test_table (data) VALUES ('before failover');"
# 步骤3:模拟主库故障(终止主库进程)
pkill -9 postgres
# 步骤4:在备库执行故障转移
psql -h standby_host -U postgres -c "SELECT pg_promote();"
# 步骤5:验证备库已晋升为主库
psql -h standby_host -U postgres -c "SELECT pg_is_in_recovery();" # 应返回f
# 步骤6:验证数据完整性
psql -h standby_host -U postgres -d test_db -c "SELECT * FROM test_table;" # 应包含新增数据2. 基于pg_rewind的手动故障转移
当主备差距较大时,可以使用pg_rewind快速同步:
bash
# 步骤1:模拟主库故障
pkill -9 postgres
# 步骤2:在备库晋升为主库
psql -h standby_host -U postgres -c "SELECT pg_promote();"
# 步骤3:修复原主库并使用pg_rewind同步
pg_ctl start -D /var/lib/postgresql/14/main -o "-c port=5433"
pg_rewind -D /var/lib/postgresql/14/main --source-server="host=standby_host port=5432 user=postgres"
# 步骤4:将原主库配置为新主库的备库
psql -h primary_host -p 5433 -U postgres -c "
STOP REPLICA;
ALTER SYSTEM SET primary_conninfo = 'host=standby_host port=5432 user=replicator password=password';
START REPLICA;
"
# 步骤5:验证新的主备关系
psql -h standby_host -U postgres -c "SELECT * FROM pg_stat_replication;"自动故障转移测试
1. Patroni集群故障转移测试
bash
# 步骤1:查看Patroni集群状态
patronictl -c /etc/patroni/patroni.yml list
# 步骤2:模拟主库故障
patronictl -c /etc/patroni/patroni.yml failover
# 或直接终止主库进程
pkill -9 postgres
# 步骤3:监控故障转移过程
patronictl -c /etc/patroni/patroni.yml watch
# 步骤4:验证故障转移结果
patronictl -c /etc/patroni/patroni.yml list # 应显示新的主库
# 步骤5:验证数据完整性
psql -h new_primary_host -U postgres -d test_db -c "SELECT * FROM test_table;"2. PostgreSQL Automatic Failover (PAF)测试
bash
# 步骤1:检查PAF状态
pcs status
# 步骤2:模拟主库故障
pcs resource failover postgresql-master
# 步骤3:监控故障转移
pcs status
# 步骤4:验证结果
pcs status | grep postgresql-master # 应显示在新节点上运行应用程序验证
1. 连接字符串配置
确保应用程序使用正确的连接字符串,支持自动重连:
java
// Java连接字符串示例
String url = "jdbc:postgresql://load_balancer:5432/test_db?sslmode=require&connectTimeout=5000&socketTimeout=30000&reWriteBatchedInserts=true&autoReconnect=true";2. 验证应用程序自动重连
bash
# 步骤1:启动应用程序并持续写入数据
java -jar test_app.jar
# 步骤2:执行故障转移
patronictl -c /etc/patroni/patroni.yml failover
# 步骤3:检查应用程序日志
grep -i "reconnect" app.log # 应显示自动重连信息
# 步骤4:验证数据连续性
psql -h new_primary_host -U postgres -d test_db -c "SELECT count(*) FROM test_table;" # 数据应持续增长故障转移时间测量
1. 手动测量
bash
# 步骤1:开始计时
echo "Start time: $(date +%s.%N)" > failover_time.log
# 步骤2:执行故障转移
pkill -9 postgres
psql -h standby_host -U postgres -c "SELECT pg_promote();"
# 步骤3:结束计时
echo "End time: $(date +%s.%N)" >> failover_time.log
# 步骤4:计算故障转移时间
t1=$(grep "Start time" failover_time.log | awk '{print $3}')
t2=$(grep "End time" failover_time.log | awk '{print $3}')
echo "Failover time: $(echo "$t2 - $t1" | bc) seconds"2. 使用监控工具测量
通过Prometheus+Grafana监控以下指标:
pg_stat_wal_receiver.replay_lag:备库回放延迟pg_up:实例可用性patroni_cluster_members:Patroni集群成员状态
故障转移测试最佳实践
1. 测试前准备
- 通知相关团队(开发、运维、业务)
- 备份所有配置和数据
- 准备回滚方案
- 确保监控和告警正常
2. 测试中注意事项
- 记录每一步操作和结果
- 监控系统资源使用情况
- 检查日志文件
- 验证数据一致性
3. 测试后验证
sql
-- 检查数据库状态
SELECT pg_is_in_recovery();
-- 检查WAL位置
SELECT pg_current_wal_lsn();
-- 验证数据完整性
SELECT * FROM test_table ORDER BY id DESC LIMIT 10;
-- 检查复制状态(如果有新的备库)
SELECT * FROM pg_stat_replication;
-- 检查连接数
SELECT count(*) FROM pg_stat_activity;4. 恢复原主库
bash
# 修复原主库
pg_ctl start -D /var/lib/postgresql/14/main
# 将原主库配置为新主库的备库
psql -h primary_host -U postgres -c "
STOP REPLICA;
ALTER SYSTEM SET primary_conninfo = 'host=new_primary_host port=5432 user=replicator password=password';
START REPLICA;
"
# 验证新的主备关系
psql -h new_primary_host -U postgres -c "SELECT * FROM pg_stat_replication;"常见故障场景测试
1. 主库崩溃
测试步骤:
- 终止主库进程
- 执行故障转移
- 验证备库晋升为主库
预期结果:
- 故障转移时间 < 30秒
- 数据无丢失
- 应用程序自动重连
2. 网络中断
测试步骤:
- 断开主库网络连接
- 等待自动故障转移
- 恢复主库网络
预期结果:
- 高可用软件能检测到网络故障
- 自动切换到备库
- 原主库恢复后能作为备库重新加入集群
3. 存储故障
测试步骤:
- 模拟主库存储故障(挂载只读或断开存储)
- 执行故障转移
- 验证数据一致性
预期结果:
- 故障转移成功
- 数据一致
- 无数据丢失
监控和告警验证
1. 监控指标验证
sql
-- 检查监控指标是否正常
SELECT
datname,
xact_commit,
xact_rollback,
blks_read,
blks_hit
FROM pg_stat_database;2. 告警验证
- 主库宕机告警
- 故障转移完成告警
- 备库延迟告警
- 应用连接失败告警
常见问题处理
1. 故障转移后数据不一致
问题:故障转移后,备库数据与原主库不一致
解决方法:
- 检查WAL归档是否完整
- 使用pg_rewind同步原主库
- 重新初始化备库
2. 应用程序无法自动重连
问题:故障转移后,应用程序无法自动重连到新主库
解决方法:
- 检查连接字符串配置
- 确保应用程序支持自动重连
- 检查负载均衡器配置
3. 故障转移时间过长
问题:故障转移时间超过预期(>30秒)
解决方法:
- 优化备库配置(如wal_buffers、checkpoint_completion_target)
- 调整高可用软件的检测间隔
- 减少备库回放延迟
测试报告模板
1. 测试基本信息
| 项目 | 内容 |
|---|---|
| 测试日期 | YYYY-MM-DD |
| 测试人员 | 姓名 |
| 测试环境 | 生产/测试 |
| 高可用架构 | Patroni/PAF/自定义 |
| 主库版本 | PostgreSQL 14.5 |
| 备库数量 | 2 |
2. 测试结果
| 测试场景 | 测试结果 | 故障转移时间 | 数据一致性 | 应用重连 |
|---|---|---|---|---|
| 主库崩溃 | 成功/失败 | XX秒 | 一致/不一致 | 成功/失败 |
| 网络中断 | 成功/失败 | XX秒 | 一致/不一致 | 成功/失败 |
| 存储故障 | 成功/失败 | XX秒 | 一致/不一致 | 成功/失败 |
3. 问题和改进
| 问题描述 | 严重程度 | 解决方法 | 负责人 |
|---|---|---|---|
| 故障转移时间过长 | 高/中/低 | 调整检测间隔 | 张三 |
| 应用重连失败 | 高/中/低 | 优化连接字符串 | 李四 |
常见问题(FAQ)
Q1:如何测量故障转移时间?
A1:可以通过以下方式测量:
- 使用脚本记录故障转移前后的时间戳
- 通过监控系统查看主库宕机到备库晋升的时间
- 使用应用程序日志记录重连时间
Q2:故障转移测试会影响生产环境吗?
A2:会,因此:
- 应在维护窗口进行测试
- 提前通知相关团队
- 准备回滚方案
- 建议先在测试环境验证
Q3:如何验证故障转移后的数据一致性?
A3:验证方法:
- 比较故障转移前后的数据量
- 检查关键业务数据
- 使用pg_verifybackup工具验证备份
- 检查WAL位置是否一致
Q4:自动故障转移失败怎么办?
A4:处理步骤:
- 手动执行故障转移
- 检查高可用软件日志
- 分析失败原因
- 修复问题后重新测试
Q5:如何优化故障转移时间?
A5:优化方法:
- 调整高可用软件的检测间隔
- 优化备库配置,减少回放延迟
- 使用更快的存储设备
- 减少主库的WAL生成速率
Q6:故障转移后需要做什么?
A6:后续工作:
- 验证数据一致性
- 检查应用程序连接
- 将原主库恢复为备库
- 更新监控配置
- 记录测试结果
Q7:如何模拟主库故障?
A7:模拟方法:
- 终止主库进程:
pkill -9 postgres - 断开网络连接:
iptables -A INPUT -p tcp --dport 5432 -j DROP - 挂载存储为只读:
mount -o remount,ro /var/lib/postgresql
Q8:如何准备故障转移测试?
A8:准备工作:
- 备份当前配置和数据
- 准备测试计划和测试用例
- 通知相关团队
- 确保监控和告警正常
- 准备回滚方案
