Skip to content

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. 主库崩溃 ​

测试步骤:

  1. 终止主库进程
  2. 执行故障转移
  3. 验证备库晋升为主库

预期结果:

  • 故障转移时间 < 30秒
  • 数据无丢失
  • 应用程序自动重连

2. 网络中断 ​

测试步骤:

  1. 断开主库网络连接
  2. 等待自动故障转移
  3. 恢复主库网络

预期结果:

  • 高可用软件能检测到网络故障
  • 自动切换到备库
  • 原主库恢复后能作为备库重新加入集群

3. 存储故障 ​

测试步骤:

  1. 模拟主库存储故障(挂载只读或断开存储)
  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:处理步骤:

  1. 手动执行故障转移
  2. 检查高可用软件日志
  3. 分析失败原因
  4. 修复问题后重新测试

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:准备工作:

  • 备份当前配置和数据
  • 准备测试计划和测试用例
  • 通知相关团队
  • 确保监控和告警正常
  • 准备回滚方案