news 2026/10/13 11:06:59

基于pgpool-II的PostgreSQL高可用与读写分离实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于pgpool-II的PostgreSQL高可用与读写分离实战指南

先说背景,这套方案是我在维护一套核心业务系统时逐步打磨出来的,当时线上刚好遇到主库磁盘告警导致服务不可用的“事故”,从那次之后就把高可用方案彻底重构了一遍。上一篇文章里已经聊了如何基于流复制搭出一主一备的基础架构,这篇重点放在pgpool-II上,目标很简单:让主库挂了以后应用几乎无感切换,同时把只读查询和写操作的流量分开,让备库也真正干活,而不是当纯摆设。如果你正在做PostgreSQL高可用,或者被读写分离搞得头大,这篇文章应该能省你不少事。

说实话,pgpool-II这个组件放在PostgreSQL生态里属于“老熟人”级别,但用好的真不多。很多文章只讲怎么装、怎么启动,从来没告诉你它内部是怎么检测故障的,failover脚本里到底该写什么东西,为什么切换完了负载均衡不生效。这些坑我一个一个踩过来,今天把能说的全写出来。

1. 为什么在 PostgreSQL 高可用里选 pgpool

先说清楚一个根本问题:PostgreSQL自身的高可用能力其实很强,尤其流复制机制非常成熟,但它在“客户端接入层”是缺位的。你不可能让每个应用自己去感知主备切换、自己改连接地址,那会把人逼疯。pgpool-II解决的就是这个接入层的问题,它充当应用和数据库之间的“交通调度员”。

1.1 它到底解决了什么痛点

  • 连接池:应用频繁创建数据库连接的代价很大,pgpool可以在中间做连接复用,几百个并发连接压缩到几十个后端连接,对数据库非常友好。
  • 自动故障转移:主库异常时,pgpool通过健康检查机制感知节点故障,自动提升备库为新主库,并且切掉到旧主库的连接,应用端的连接被透明地转移到新主库。
  • 读写分离:PostgreSQL自身只能通过第三方插件或者中间层做读写分离,pgpool根据SQL语句类型进行自动路由,SELECT走备库,INSERT/UPDATE/DELETE走主库。
  • 负载均衡:在有多个只读节点时,pgpool可以把读请求分发到不同的备库,分散压力。

这四个能力单独拎出来,随便一个都值得用pgpool。四个加在一起,基本上就是中小团队不需要自研代码就能拿到的高可用完整方案。

1.2 对比其他方案,pgpool输不输

我见过有人用HAProxy做读写分离,也有人用Patroni+etcd做自动切换。不能说哪个绝对好,但pgpool有个非常明显的差异化优势:它内置了SQL级别的读写判别逻辑,而不是像HAProxy那样只能做IP和端口级别的转发。你让HAProxy去区分SELECT和UPDATE,它是做不到的,除非你自己搞中间件解析协议。

Patroni很强,强在自动选主和分布式一致,但它偏重配置、依赖etcd等外部组件,运维心智成本高。pgpool-II可以在不引入额外分布式组件的前提下完成主从切换和读写分离,这对很多只有一两套PostgreSQL环境的团队来说,部署成本和理解门槛都低得多。当然,它的watchdog模块也能实现多节点仲裁,后面展开说。

2. 环境准备与整体架构设计

干活之前先把架构图在脑子里画清楚。一个标准的pgpool读写分离+高可用架构通常包含这些角色:

应用客户端 | | 读写分离 + 连接池 + 故障转移 v Pgpool-II节点(建议双节点部署,配合watchdog做守护) | +--------------+--------------+ | | v v 主库(Primary) 备库(Standby) 流复制 流复制

2.1 版本兼容性这件事先搞清楚

我踩过最典型的坑是版本匹配。pgpool-II不同版本对PostgreSQL的支持范围是不一样的,直接决定你后面能不能愉快地用它的在线恢复等功能。我当前使用的是pgpool-II 4.4 + PostgreSQL 14,配合良好。如果你用的是PostgreSQL 15/16,最好选择pgpool-II 4.4及以上版本,具体支持矩阵官方文档里有明确说明,动手前先花两分钟确认,别装完以后发现功能缺失再返工。

在生产环境里我建议直接用官方编译好的RPM或者二进制包,而不是从源码编译。前者省事,后者你要处理一堆依赖问题,纯属给自己加戏。但如果你内网环境没有现成的包源,编译装也问题不大,核心依赖是libpq和OpenSSL。

2.2 机器规划

以最常见的双节点pgpool为例,最少三台机器:

主机角色说明
node1Pgpool节点A + 主库可以同机部署,也可以分开
node2Pgpool节点B + 备库同上
node3业务应用节点连接pgpool虚拟IP

生产上我更推荐把pgpool和PostgreSQL分开部署,原因很简单:故障隔离。如果pgpool和主库在同一台机器,主库机器宕机直接连pgpool也一起没了,高可用意义大打折扣。预算不够时同机部署也只能接受,但至少pgpool节点要双份,用watchdog做热备。

2.3 提前规划虚拟IP

pgpool的高可用集群需要对外提供一个漂移IP,也就是虚拟IP(VIP)。应用只连这个IP,发生主从切换时VIP会自动从故障节点漂移到存活节点。这个灵活性很关键:如果应用直连某个pgpool节点,那个节点挂了应用照样连不上,VIP就是为了解决这个问题。

VIP的规划建议与业务网段一致,提前预留好,不要在部署当天临时选,避免改路由权限等尴尬情况。

3. pgpool核心机制:它是怎么实现切换和读写分离的

很多文章上来就贴配置,不解释原理。这就导致出问题时不知道怎么调试。我先用通俗的话拆一下pgpool的内部机制,明白这些以后你再看配置,基本一眼就知道每个参数在干什么。

3.1 健康检查:pgpool怎么知道数据库挂了

pgpool会定期向后端数据库发送心跳探测信号,这个机制叫health check。它有两种最主要的方式:

  • 通过TCP连接检测端口是否活
  • 通过真实查询(比如SELECT 1)验证数据库可用性

后者比前者更靠谱,因为有些时候端口还在,但数据库已经僵死,比如进程假死、事务挂起耗尽连接数等。这种情况TCP检测发现不了,但查询检测能发现。所以配置中我强烈建议开启查询检测,把health_check_period设置成合适的间隔。

间隔多长时间看你的业务容忍度。设置太短,比如3秒,数据库稍有波动就触发切换,反而影响稳定性;设置太长,故障后应用被迫等待很久。我的个人经验是health_check_period = 10,配合health_check_timeout = 5,整体故障感知时长控制在15秒左右。当然你也可以往下压,但要经过充足测试。

3.2 故障切换的三个阶段

pgpool检测到主库故障后,会触发一个failover流程,这个流程大致分三步:

  1. 标记节点异常:pgpool把故障节点从可用节点列表里摘除,后续不再把新请求往故障节点上分发。
  2. 执行脚本:调用你配置的failover_command,这个脚本由DBA自己编写,通常用于提升备库为新主库。
  3. 节点角色迁移:pgpool内部重新维护主备角色信息,随后的读写请求按照新的角色分配。

注意一个细节,pgpool本身并不执行“ALTER SYSTEM SET ...”,它只是一个协调者,真正让备库变成主库的动作,靠的是你在脚本里调用pg_ctl promote或通过SELECT pg_promote()完成。这个脚本写不好,切换就会半途而废。

3.3 读写分离是怎么判断的

pgpool的读写分离不是靠监听端口、也不是靠正则匹配,而是做了SQL解析,识别语句类型。Sentinel逻辑大致是:

  • SELECT开头,没有FOR UPDATE、没有写函数,路由到备库。
  • INSERT / UPDATE / DELETE / DDL,路由到主库。
  • 事务内语句默认全部走主库,除非开启allow_sql_comments等特殊选项。

这个机制本身很成熟,但有个容易踩的坑:如果在事务中先执行写操作,再执行查询,pgpool会为了保持事务一致性把所有后续语句都发到主库。个别业务觉得这样不够“负载均衡”,但你反过来想,如果查询读到的是备库上还没同步到的旧数据,那才是灾难。所以这个行为不是bug,是保护机制。别想着关掉它,除非你完全能容忍短暂不一致。

4. 核心配置与实操步骤

下面进入正文的重头戏。我把整个配置拆分成三个大块:后端节点注册、故障切换配置、读写分离配置。三块均给出可直接抄走的配置段,并解释每个参数的作用。

4.1 后端节点注册与用户认证

打开pgpool.conf,首先要配置后端节点信息。常见配置项如下:

# 后端节点数量,这里是一主一备两个节点 backend_hostname0 = '192.168.10.101' backend_port0 = 5432 backend_weight0 = 1 backend_data_directory0 = '/var/lib/pgsql/14/data' backend_hostname1 = '192.168.10.102' backend_port1 = 5432 backend_weight1 = 1 backend_data_directory1 = '/var/lib/pgsql/14/data'

说明一下backend_data_directoryx这个参数,很多人忽略它。它必须和lsync在线恢复功能配合使用,如果你不打算用pgpool的在线恢复功能,也可以不写。但写上没坏处,因为它还能帮助pgpool在故障切换时更快确定节点状态。

权重参数backend_weightx的意思是:读请求的负载均衡权重。一主一备时两个权重都设为1,读请求各50%。如果你不想让备库承担太多读压力,可以把备库权重调低到0.3,让约23%的读请求到备库。这个参数非常灵活,按业务需求来。

节点注册完成后,还要为pgpool配置数据库用户认证。pgpool需要能连接后端数据库去执行健康检查和故障切换,自然需要用到账户。建议不要用超级用户跑日常连接,专门创建一个具备必要权限的管理账户,比如:

CREATE USER pgpool_user WITH REPLICATION; CREATE USER app_user WITH PASSWORD 'your_password';

4.2 主从自动切换的完整配置

故障切换最核心的配置有三项:

health_check_period = 10 health_check_timeout = 5 health_check_user = 'pgpool_user' health_check_password = 'your_password' health_check_database = 'postgres' # 故障切换时执行的脚本 failover_command = '/etc/pgpool/failover.sh %d %H %R'

关于failover_command的传参,这是极其重要又容易写错的部分。pgpool在执行脚本时会传入一系列参数,%d是宕机节点的ID,%H是新主库的主机名,%R是新主库的数据目录。你要在脚本里把这些参数接住。

下面是我生产环境里一份验证过很多次的failover脚本,可直接借鉴:

#!/bin/bash # failover.sh # 参数说明: # $1 = failed node id (被标记为故障的节点ID) # $2 = new master host (pgpool决定提升为主库的节点主机名) # $3 = new master data dir (新主库的数据目录) FAILED_NODE_ID="$1" NEW_MASTER_HOST="$2" NEW_MASTER_DATA_DIR="$3" LOG_FILE="/var/log/pgpool/failover.log" echo "$(date '+%Y-%m-%d %H:%M:%S') failover triggered. failed_node=$FAILED_NODE_ID new_master=$NEW_MASTER_HOST dir=$NEW_MASTER_DATA_DIR" >> $LOG_FILE # 在备库上提升其为主库 if [ "${NEW_MASTER_HOST}" != "" ]; then ssh postgres@${NEW_MASTER_HOST} "/usr/pgsql-14/bin/pg_ctl promote -D ${NEW_MASTER_DATA_DIR}" >> $LOG_FILE 2>&1 fi # 注意:这里不是强制要求ssh操作,也可以采用其他方式远程执行 exit 0

这段脚本的逻辑不复杂,但有几个细节值得强调。

第一,pg_ctl promote需要在备库所在机器上执行。如果你的pgpool与数据库分离部署,脚本是在pgpool机器上执行的,所以要通过SSH远程过去执行提升操作。SSH免密登录这一步提前配置好,否则切换时脚本卡在密码输入处,整个故障转移就废了。

第二,脚本开头建议写日志这个动作,别省。没有日志你根本不知道failover脚本有没有被触发,有没有报错。先在本地落一条活生生的记录,排查问题时你会感谢自己。

第三,脚本权限。创建完脚本后记得chmod +x,并且把属主设为pgpool运行所用的操作系统用户,否则可能执行不了。

另一个需要配置的是follow_primary_command,它的作用是当新主库产生后,旧备库要重新跟新主库建立流复制。在当前场景(只有一主一备)故障切换时,旧主库宕机,新备库的角色就是空的,不需要再配置。当你有两个以上备库时,你必须配置它,否则其他备库不知道新的复制源是谁,会停在原地等。

4.3 读写分离的配置

读写分离的控制关键在load_balance_mode和master_slave_mode这两个开关:

load_balance_mode = on master_slave_mode = on master_slave_sub_mode = 'stream'

master_slave_sub_mode = 'stream'是让pgpool知道后端用的是流复制,它才能正确识别主备。有人会在无意中把这个参数漏掉,导致pgpool仍然用旧的“主从复制”逻辑判断,负载就不对。这三个参数必须同时开启。

还有一个容易被忽略的参数:white_function_list和black_function_list。它俩用来定义“哪些函数是写函数、哪些是读函数”。比如公司业务里普遍用nextval('seq')获取序列值,这个实际上属于写操作,会修改数据库状态。pgpool如果不知道,可能会试着把包含nextval()的查询路由到备库,导致序列值在不同库不一致,甚至报错。解决办法就是把它列入黑名单:

black_function_list = 'nextval,setval,pg_advisory_lock,pg_try_advisory_lock'

同样,如果你有一些自定义的只读函数(比如查只读视图的封装函数),可以把它加入white_function_list。一般建议宁可多列黑名单,也不要乱导流。

4.4 watchdog的守护配置

高可用的pgpool需要禁得起单点pgpool故障的考验。这里就轮到watchdog模块上场。watchdog用于监控pgpool自身节点,当某个pgpool节点故障时,另一个接管VIP。配置中需要开启watchdog并定义节点。

use_watchdog = on wd_hostname = '192.168.10.101' wd_port = 9000 wd_interval = 5 # 本节点的其他连接信息 wd_lifecheck_query = 'SELECT 1' wd_lifecheck_dbname = 'postgres' wd_lifecheck_user = 'pgpool_user' # 配置参与竞选的pgpool节点列表 other_pgpool_hostname0 = '192.168.10.102' other_pgpool_port0 = 9999 other_wd_port0 = 9000 # 虚拟IP设置 delegate_IP = '192.168.10.200' ifconfig_path = '/sbin' if_up_cmd = '/usr/sbin/arping -q -U -c 3 192.168.10.200' if_down_cmd = 'ip addr del 192.168.10.200/24 dev eth0'

Watchdog的配置比我写的要多不少,但核心逻辑就是上面这些。有一件事必须单独强调:watchdog节点之间通信涉及网络端口和心跳协议,在云平台环境里,组播或广播方式经常受限制,我建议用单播模式,并且提前测试两台机器间的9000端口通信是否顺畅。有次我在内网云主机上卡了半天,最后发现是安全组把9000端口默认拦了,watchdog一直在报脑裂,吓得我差点回退方案。

虚拟IP的if_up_cmd中我加了arping广播,作用很简单:让同一网段的其他机器尽快刷新ARP缓存,把VIP对应的MAC地址切换过来。如果不做这一步,可能某些设备缓存了旧MAC地址,导致即使VIP漂移了,业务包还是发往旧机器,切换等于白做。

4.5 数据库端需要配合调整的参数

不要以为只熊pgpool就完事了,主库和备库自身的配置同样要跟上。

在PostgreSQL主库上,wal_level必须是replica或者更高(PG14默认是replica,因为logical已经被细分出去),max_wal_senders至少设置为2以上,预留一个给流复制,一个给基础备份和在线恢复。max_connections也别乱设,因为pgpool还会保留自己的后端连接,直接相关的是后端的max_connections决定了pgpool能复用多少连接。配合pgpool的连接池,总的会话数自然是受控的。

备库上还有一个容易被忽略的设置:hot_standby = on,开启后备库才能处理只读查询。如果这里没开,pgpool把读请求发过去,备库直接报错,读写分离就成了空谈。

配置全部改完后,先重启PostgreSQL,再重启pgpool,顺序不能反。

5. 实操演示:手动触发主从切换并验证读写分离

配置装好了,必须验证。不验证的高可用就是个玄学,没人敢保证它真能扛住事故。

5.1 验证读写分离是否生效

先用pgpool提供的命令查看后端节点状态:

pcp_node_info -h 127.0.0.1 -p 9898 -U pgpool_user -w

正常会显示两个节点,其中一个state为primary,另一个为standby。两个节点都处于up状态代表连接正常。

然后登录到备库,开启查询日志跟踪,比如临时把log_statement = all打开,看某个执行了SELECT的应用,它的连接到底是从主库还是备库出来的。更直观的办法是在PostgreSQL主备两端分别查询当前活跃会话,对比客户端来源IP:

SELECT pid, usename, client_addr, application_name, state FROM pg_stat_activity;

我自己的验证方法是:在备库上创建一个一模一样的中间表,往里面插入一行带特殊标记的数据,然后让应用执行SELECT,看能不能查到这条数据。能查到说明读请求到了备库;查不到说明还压在主库上。这个测试虽然“野”,但非常直观。

还要注意一个非常细节的验证点:直接在psql里执行SHOW transaction_isolation,你会发现通过pgpool连接数据库后,看到的client_addr是pgpool所在机器的IP,而不是应用的真实IP。这不是问题,是pgpool的代理特性。必要时可以通过backend_application_name等方式区分来源。

5.2 模拟主库故障,验证自动切换

准备好一个小窗口,保持一个长事务在应用里跑着(模拟正常业务流量),然后找一个维护窗口,手动停掉主库。

# 在主库机器上执行 pg_ctl stop -m fast

注意这里我用了-m fast,这是模拟非正常停机,会让活跃事务中断。如果直接shutdown,主库还会发一个优雅关闭的信号给备库,备库不会自己去抢主角色,这样就测不出真正的故障转移逻辑。

停掉主库后,观察pgpool日志。正常情况下你会在几秒内看到类似下面的日志:

LOG: failover: no candidate, then declare failure node LOG: starting failover process...

如果日志停在no candidate这一步,说明pgpool没能识别出一个可以提升的备库。这时先不要慌,去检查备库的流复制状态是否正常,尤其确认备库的pg_wal目录有没有在接收新数据。以前我遇到过一次,备库的replication slot坏了,备库实际已经落后主库很多,pgpool检查备库时发现数据不一致,拒绝对它做提升。这种情况下你需要先修复流复制链路,再考虑failover。

当failover正常完成后,再用pcp_node_info查节点状态,备库的角色已经变成primary,旧主库被标记为down。

同时验证一下VIP的漂移地址:

ip addr show

在原来的pgpool节点上如果看到VIP消失、在备节点上出现了VIP,说明VIP漂移成功。如果VIP没漂移,八成是watchdog状态没确认,先检查pcp_watchdog_info看看两个节点的状态是不是都在线。

5.3 恢复旧主库并让它重新成为备库

这是很多经验不足的人会漏掉的环节。主库恢复后,通常它已经比新主库的数据落后了一大截。此时绝不能直接把它加回去当主,你要做的是把它降级为备库,然后通过流复制追上最新数据。

操作流程如下:

  1. 确保旧主库的data目录不变。
  2. 修改旧主库的postgresql.conf,加入或确认primary_conninfo指向新主库。
  3. 删除旧主库data目录下的standby.signal,让PostgreSQL以standby模式启动(PostgreSQL 12+的机制)。
  4. 启动旧主库,确认它变成新主库的备库。

具体命令大致是:

# 在旧主库机器上 rm -f $PGDATA/standby.signal cat > $PGDATA/postgresql.conf.append <<EOF primary_conninfo = 'host=192.168.10.102 port=5432 user=replicator application_name=standby1' EOF pg_ctl start

启动后观察新主库的pg_stat_replication,看到旧主库的进程在线且state=streaming,说明恢复成功。然后也在pgpool里把节点重新加回来:

pcp_attach_node -h 127.0.0.1 -p 9898 -U pgpool_user -n 0

把节点重新挂载后,pgpool会把它作为备库纳入读写分离池。这一步一定要等流复制同步追平后做,不然这个节点会拖累整体负载均衡的可用性。

6. 常见问题与排查技巧实录

问题1:failover半天不触发,日志里也没动静

处理思路:先确认health_check_period和health_check_timeout配得是否太保守。如果主库进程彻底僵死但端口还开着,health_check_timeout太短可能导致检测误判;如果health_check_period太长,故障感知自然慢。我实践中还遇到过一种隐蔽情况:pgpool的health_check_user密码过期或被误改,导致健康检查一直失败但pgpool日志里错误级别不高,你没注意到。排查这个问题的第一手段就是把pgpool日志级别调到LOG或DEBUG1,然后手动SELECT pg_terminate_backend(pg_backend_pid())制造一次断连,观察日志反应。

问题2:切换成功了,但应用连接还是一直报错

你确认pgpool日志里已经执行了failover,新主也已经提升成功,但应用还在报“connection refused”。这种情况大概率是因为应用侧连接池还保留着旧连接,没有感知到数据库端连接被断开。pgpool在failover后应该会主动断开到故障节点的连接,但如果应用侧用的是长连接且没有设置合理的连接存活检测,一直复用旧连接自然会失败。

解决办法有两步:应用端连接池配置里开启连接有效性检测,比如HikariCP的connection-test-query和validation-timeout;pgpool侧把client_idle_limit设一个合理值,长时间空闲的连接自动断开,倒逼应用新建连接。这个组合拳能有效缓解切换后的“僵尸连接”问题。

问题3:读流量没到备库去

这是新手最容易遇到的现象:配置用了读写分离,但备库的查询日志一点动静没有。检查顺序如下:

  1. load_balance_mode和master_slave_mode是否都为on。
  2. master_slave_sub_mode是否是stream。
  3. 查看pcp_node_info里两个节点的weight是不是都不为0。
  4. 检查是否有显式在这个会话里发过写语句,导致会话级别强制走主库。

前三个没问题的话,十有八九是会话级行为。很多应用框架会默认在同一个连接里使用事务,而事务内读请求默认全部主库,这是最最常见的“读写分离不生效”的原因。如果你用的是ORM框架(比如Hibernate),又开启了事务,所有的SELECT都会走主库,从备库日志上看起来就像完全没有负载均衡。处理方式:要么把只读查询单独走只读连接,要么在pgpool里开启allow_sql_comments来强制某些语句路由到备库(但这是高级玩法,不推荐无脑用)。

问题4:watchdog脑裂

所谓脑裂是指两个pgpool节点同时认为自己才该持有VIP,导致网络风暴或者业务连接混乱。表现是VIP在两个节点间跳来跳去,应用连接频繁中断。脑裂在云环境里尤其容易发生,因为云网络对ARP、组播的支持与物理机不同。

排查方法:看watchdog日志,确认两个节点互相能ping通、9000端口能通;检查wd_lifecheck的配置,确认wd_hostname写的是本机实际IP,而不是127.0.0.1。事实上很多脑裂就是wd_hostname写错导致节点间互相误判对方失联。出现脑裂后,先人工指定一台为权威节点,把另一个节点的watchdog停掉,再逐步恢复。

问题5:切换后新主库没有开启只读处理能力

有时候你按脚本执行了pg_ctl promote,备库变成了主库,但查看pg_is_in_recovery(),发现还是t。这是因为pg_ctl promote执行时,如果备库还没有完全拿到主库的WAL日志,它其实在等待日志补齐,这个过程可能需要一点时间。别急,可以在业务维护窗口多等几秒,再验证pg_is_in_recovery()返回f。如果一直不返回,检查主备之间的WAL传输是否有断档,或者磁盘空间是不是满了。

问题6:故障切换后数据丢失

说句扎心的话,任何流复制方案都有极小概率的数据丢失窗口。因为流复制是异步的,主库崩溃时,最后产生的WAL日志可能还没来得及传给备库。pgpool本身不具备数据补齐功能,它只能把备库顶上。如果你业务零丢失是刚需,那得上同步复制sync replication,但这会降低性能,需要权衡。

我的做法是从业务层做兜底:核心写入操作在应用里双写一份到消息队列,数据库恢复后再做对账。听起来老土,但真发生切换时我睡得着觉。你也可以考虑在切换前用pg_wal里的部分日志做归档恢复,把数据捞回来。总之,别天真地以为pgpool能帮你把数据丢失变成零。

7. 一些后期运维建议

这一章不算严格技术点,但却是我在若干次真实事故里换回来的心得。

7.1 慢SQL的追踪

用pgpool后,你要特别小心“读请求全到主库”导致的慢SQL问题。开启读写分离时,一定在PostgreSQL配置里打开log_min_duration_statement,建议设1000ms,超过1秒的SQL记日志。这样一旦备库没有分担流量,你通过日志能直观发现有大量慢查询在主库执行。

7.2 备库延迟监控

备库延迟是读写分离的心腹大患。备库落后太多,读请求虽然发过去了,返回的数据却是“昨天”的。对很多业务来说这不可接受。我每天都会定时跑一次监控SQL,检查主备延迟:

SELECT pid, application_name, state, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes FROM pg_stat_replication;

如果lag_bytes持续增大,就要考虑是不是备库IO能力不足、网络带宽受限或者归档任务拖慢了备库刷盘速度。不要等到用户反馈数据不对才去查。

7.3 定期演练故障切换

这点真的重要。我见过太多团队搭好了高可用,一年都不切一次,结果真出事时,脚本执行权限错了、新主库起不来、VIP漂不过去,被发现时全已晚。

我的建议是每个月做一次模拟切换演练,时间挑在业务低峰期,切完再切回来。把每次切换的时间、日志、报错记录到运维文档里,形成自己的切换预案。演练中发现的问题才值钱,生产事故里暴露的问题代价太大。

7.4 再看一眼备份

最后这个提醒非常容易被忽略:pgpool只是高可用,不等于备份。如果说故障切换是“让人继续上班”,那备份就是“万一这个员工彻底失联,你还有档案”。流复制并不能替代定时备份。即使有了pgpool,全量备份+归档WAL的备份任务仍然必须跑,不能省。我有一个血的教训:高可用方案上线后,团队高兴了半年,结果一次误删数据事件,由于没有独立备份,恢复起来极其痛苦。从那以后我一直保留独立的备份集,每天验证备份可恢复性。

好了,pgpool做PostgreSQL高可用、主从切换和读写分离的核心细节基本都在这里了。个人最大的体会是:架构设计时别光盯着功能,还要想清楚故障转移的全链路——从健康检查到节点提升,再到应用连接重连,每一环都要能观测、可验证。踩过几次坑之后,我对自己这套方案最大的信心来源不是配置写得多漂亮,而是每一次演练都实实在在地做过。希望这篇文章能让你少走弯路,如果有其他问题,欢迎顺着实操步骤去验证,测试环境多折腾几次比什么都强。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 11:06:56

Unity VR太阳系开发:天体力学引擎与坐标系优化实战

简介&#xff1a;这是一份基于Unity 3D引擎开发的太阳系VR沉浸式教学与交互演示资源&#xff0c;面向VR开发初学者、教育技术从业者及天文科普内容创作者&#xff0c;解决三维天体运动模拟与虚拟现实交互实践缺乏可运行案例的问题。资源共2000个文件&#xff0c;主体为220个C#脚…

作者头像 李华
网站建设 2026/10/13 11:06:51

TensorFlow计算图核心拆解:张量、op与Session运行机制

1. TensorFlow是谁&#xff0c;为什么从它入手学深度学习1.1 深度学习框架到底帮你省了什么先说个最朴素的问题&#xff1a;深度学习框架到底是干什么的&#xff0c;为什么所有学习路线图都会让你先装一个&#xff1f;如果完全手写一个神经网络&#xff0c;你至少要做三件事。第…

作者头像 李华
网站建设 2026/10/13 11:05:42

MES工艺卡片公式批量导入XHEDITOR:从Excel到网页编辑器的完整实践

做汽车行业MES相关工作的人&#xff0c;多半都遇到过这样一个有点“鸡肋”的需求&#xff1a;工艺卡片要从Excel台账、老Word文件、甚至扫描PDF里&#xff0c;把那些看起来不起眼、但车间老师傅特别较真的公式&#xff0c;成批导入到网页端的工艺编辑器&#xff08;比如标题里说…

作者头像 李华
网站建设 2026/10/13 11:05:27

Postman脚本加密JSON报文:动态参数与签名避坑指南

我记得年前联调一个对公接口时&#xff0c;同事在本地脚本里跑得好好的&#xff0c;挪到 Postman 里就报验签失败。一开始怀疑算法写错了&#xff0c;后来一行行对比才发现&#xff1a;报文体里有三个动态字段&#xff0c;脚本每次生成的顺序和取值时机不同&#xff0c;导致参与…

作者头像 李华
网站建设 2026/10/13 11:04:57

从结果倒推设计产品方案:目标翻译、路径逆拆与最小闭环

做方案这件事&#xff0c;很多人有个惯性&#xff1a;拿到需求先顺着想。顺着用户场景想&#xff0c;顺着现有功能想&#xff0c;顺着资源限制想&#xff0c;最后排一版看起来哪儿都对的计划。但执行到一半往往才反应过来&#xff0c;整条路从一开始就没指向真正要的结果。我经…

作者头像 李华