PostgreSQL高可用集群实战:pgpool-II读写分离与故障转移搭建指南
1. 为什么要搭这套集群先把话放前面数据库单点早晚出事。别管你是跑一个小网站还是支撑核心业务只要 PostgreSQL 还挂在一台机器上那么硬盘故障、内核 panic、机房断电、运维误操作任何一件小事都能让服务直接停摆。所以我一直建议数据库层的高可用不是可选项是刚需。pgpool-II 是 PostgreSQL 生态里一个老牌中间件它同时干几件事连接池、负载均衡、自动故障转移。和 Patroni 这类偏“数据库自治”的方案相比pgpool-II 更轻量部署直观适合中小规模团队快速搭起一套“读写分离 主备自动切换”的架构。我这次用的是 pgpool-II 4.4 系列PostgreSQL 用的是 14这两者配合非常成熟网上踩坑资料也多适合作为生产环境的基线版本。这套方案能解决什么问题简单说应用只管连 pgpool 的虚拟 IP完全不用关心后端哪台是主、哪台是备。主库挂了pgpool 自动把备库提升为新主库应用几乎无感知。读请求能在主备之间分发减轻主库压力。连接被 pgpool 统一管理避免应用直连数据库导致连接数被打爆。适合谁来参考正在用 PostgreSQL 做业务库、想解决单点故障的小团队或者刚接手数据库运维、想系统学一下高可用机制的开发者。文章里我会把架构设计、配置步骤、故障转移验证、常见坑全部过一遍。2. 架构设计与资源规划2.1 拓扑结构我这边采用两节点方案一台主库、一台备库中间放两台 pgpool 做守护为什么要两台 pgpool因为 pgpool 本身也有单点问题。如果只有一台 pgpool它挂了后端数据库再健康应用也连不上。所以生产环境至少两台 pgpool配合虚拟 IPVIP keepalived 做主备切换才能保证整个接入层也是高可用的。整体拓扑如下应用连接 VIP比如 192.168.1.100VIP 由两台 pgpool 节点共享pgpool 节点 1192.168.1.11和节点 2192.168.1.12互为主备后端 PostgreSQL 主库192.168.1.21和备库192.168.1.22通过流复制保持数据同步pgpool 负责把读请求分发到主备写请求强制走主库在这个架构里数据流向是应用 → keepalived VIP → pgpool → PostgreSQL。任何一个环节失效都有对应的切换机制兜底。2.2 主机规划我建议所有节点都使用独立物理机或虚拟机不要搞容器化一锅炖数据库这种有状态的服务先跑在裸机或 VM 上最踏实。我的规划如下主机名IP地址角色配置建议pg-node1192.168.1.21PostgreSQL 主库4核8GSSD 100Gpg-node2192.168.1.22PostgreSQL 备库4核8GSSD 100Gpgpool-node1192.168.1.11pgpool 主节点 keepalived MASTER2核4Gpgpool-node2192.168.1.12pgpool 备节点 keepalived BACKUP2核4G操作系统我选的是 CentOS 7.9虽然不是最新但胜在稳定pgpool 官方仓库对它的支持一直很好。如果你的环境是 Rocky Linux 9 或者 Ubuntu 22.04配置逻辑一样就是包管理器命令略有差异。2.3 版本选择说明PostgreSQL 14 和 pgpool-II 4.4 是我目前比较放心的一对组合。PostgreSQL 14 的流复制已经很成熟pgpool 4.4 对 PostgreSQL 14 的pg_rewind支持也很好故障切换后老主库重新加入集群时可以通过pg_rewind快速同步增量数据不需要重建整个备库。这个点很重要。早期版本的 pgpool 配合 PostgreSQL 处理老主库回归时常常要全量重建数据量大时非常痛苦。有了pg_rewind老主库能像“增量备份恢复”一样追上新主库速度快很多。3. PostgreSQL 主备流复制搭建3.1 基础环境配置两台 PostgreSQL 节点都需要做同样的基础配置。首先关闭防火墙或者放行端口我建议直接放行测试环境别在防火墙层面浪费时间生产环境按公司安全规范操作systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/config然后配置 hosts确保节点之间可以通过主机名互相解析cat /etc/hosts EOF 192.168.1.21 pg-node1 192.168.1.22 pg-node2 192.168.1.11 pgpool-node1 192.168.1.12 pgpool-node2 EOF3.2 安装 PostgreSQL 14我用的是 PostgreSQL 官方 YUM 仓库安装过程不复杂yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install -y postgresql14-server postgresql14-contrib装完后初始化数据目录。注意 PostgreSQL 14 使用initdb初始化时默认会创建一个超级用户我建议先设置好密码再初始化省得后面再改/usr/pgsql-14/bin/postgresql-14-setup initdb systemctl start postgresql-14 systemctl enable postgresql-14接着设置 postgres 用户密码su - postgres psql -c ALTER USER postgres PASSWORD YourStrongPassword;3.3 主库配置主库的配置核心是开启归档和流复制。编辑/var/lib/pgsql/14/data/postgresql.conflisten_addresses * port 5432 wal_level replica max_wal_senders 10 wal_keep_size 1024 archive_mode on archive_command test ! -f /backup/pgwal/%f cp %p /backup/pgwal/%f这里解释一下几个关键参数max_wal_senders允许多少个备库连接主库拉取 WAL2 个节点就够我设 10 是为了留余量wal_keep_size主库保留多少 WAL 供备库追赶如果备库断连太久WAL 被回收就需要重新全量同步1024MB 是个比较稳妥的初始值archive_command归档 WAL 到本地目录这个在故障切换后有用保证数据不丢然后配置pg_hba.conf允许备库和 pgpool 节点连接host replication postgres 192.168.1.0/24 md5 host all postgres 192.168.1.11/32 md5 host all postgres 192.168.1.12/32 md5 host all all 192.168.1.0/24 md5这里要特别提醒replication那条记录是给流复制用的pgpool 的健康检查走的是普通连接。千万别把这两类权限搞混不然故障转移时 pgpool 会报权限不足。3.4 备库搭建备库搭建的第一步是从主库做一次全量基础备份。在备库上执行su - postgres /usr/pgsql-14/bin/pg_basebackup -h pg-node1 -U postgres -D /var/lib/pgsql/14/data -P -R -X stream几个参数的含义-R自动生成 standby.signal 文件和 recovery 配置这样备库启动时就知道自己是一个待命节点-X stream通过流复制方式传输 WAL不需要等归档速度更快执行成功后journalctl 确认备库能正常启动systemctl start postgresql-14 systemctl enable postgresql-14这时候在主库执行psql -c select * from pg_stat_replication;应该能看到一条备库的连接记录。看到state: streaming就说明流复制已经跑起来了。3.5 验证流复制建一张测试表插入数据然后分别在主备上查询确认数据一致-- 主库执行 CREATE TABLE tb_test (id int primary key, name text); INSERT INTO tb_test VALUES (1, hello);备库执行查询SELECT * FROM tb_test;如果备库能查到(1, hello)说明同步链路正常。这个步骤不能省很多配置错误要到故障切换时才暴露那就晚了。4. 安装与配置 pgpool-II4.1 安装 pgpool-II两台 pgpool 节点都安装 pgpool 和 keepalivedyum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install -y pgpool-II-14 keepalived注意这里是pgpool-II-14这个 14 代表它匹配 PostgreSQL 14 的扩展版本不要装成 13 或者 15版本不对会有兼容性问题。安装完成后pgpool 的配置文件在/etc/pgpool-II/主要文件有pgpool.conf主配置文件pcp.conf管理接口认证文件pool_hba.conf客户端认证配置4.2 pgpool.conf 核心配置先不啰嗦直接给一份能跑通的配置然后逐段解释listen_addresses * port 9999 socket_dir /var/run/pgpool pcp_listen_addresses * pcp_port 9898 backend_hostname0 pg-node1 backend_port0 5432 backend_weight0 1 backend_data_directory0 /var/lib/pgsql/14/data backend_flag0 ALLOW_TO_FAILOVER backend_hostname1 pg-node2 backend_port1 5432 backend_weight1 1 backend_data_directory1 /var/lib/pgsql/14/data backend_flag1 ALLOW_TO_FAILOVER enable_pool_hba on pool_passwd pool_passwd num_init_children 32 max_pool 4 child_life_time 300 connection_life_time 0这一段是基础连接配置。backend_hostname0和backend_hostname1定义了两个后端节点pgpool 会按编号 0 和 1 来区分主备。注意backend_data_directory必须填对pgpool 在故障切换时要读这个目录去执行pg_rewind填错路径会导致切换失败。然后配置健康检查和故障转移health_check_period 5 health_check_timeout 3 health_check_user postgres health_check_password YourStrongPassword health_check_max_retries 3 health_check_retry_delay 1 failover_command /etc/pgpool-II/failover.sh %d %h %p %D %m %H %M %P健康检查每 5 秒执行一次如果连续 3 次失败就触发 failover 脚本。这个频率是平衡了“故障发现速度”和“避免误判”的结果太快容易抖动误判太慢业务受影响时间长。再配置自动恢复和 watchdog两台 pgpool 之间的协调机制auto_failback on failback_command /etc/pgpool-II/failback.sh %h %H %M use_watchdog on trusted_servers pgpool-node1,pgpool-node2 delegate_IP 192.168.1.100 if_cmd_path /sbin if_up_cmd ip addr add $_IP_/24 brd 192.168.1.255 dev eth0 label eth0:0 if_down_cmd ip addr del $_IP_/24 dev eth0 heartbeat_device eth0 wd_hostname pgpool-node1 wd_port 9000 wd_hb_interval 2 wd_life_point 5 wd_lifecheck_query SELECT 1watchdog 是 pgpool 自带的高可用机制它和 keepalived 配合负责 VIP 的漂移。这里delegate_IP就是应用连接数据库时用的虚拟 IP两台 pgpool 谁会绑定这个 IP谁就是当前活跃的接入节点。主备切换这一步很重要。watchdog 本身能保证 pgpool 节点的高可用但 VIP 的漂移动作它需要系统命令配合所以还需要 keepalived 或者手动脚本。我用的是 keepalived 脚本组合后面细说。4.3 配置 pcp.confpcp 协议是 pgpool 的管理接口用于手动执行切换、查看节点状态等操作。创建 pcp 用户PGPOOL_SETUP1 /usr/pgpool-14/bin/pg_md5 YourPCPPassword /etc/pgpool-II/pcp.conf echo pgpool:YourPCPPassword /etc/pgpool-II/pcp.conf注意pg_md5生成的只是密码的 MD5 值不是明文。pcp.conf 里的格式是“用户名:MD5密码”别把明文写进去。4.4 配置 pool_hba.conf为了保证客户端认证一致我直接复用 PostgreSQL 的 hba 文件逻辑host all all 192.168.1.0/24 md5如果想在 pgpool 层面做更细粒度的权限控制可以自己加规则但test环境这样已经够用。4.5 配置前端认证pgpool 自身有一套密码认证体系它需要从 PostgreSQL 里读取用户信息并生成 pool_passwd 文件/usr/pgpool-14/bin/pg_md5 -p -m -u postgres YourStrongPassword mv pool_passwd /etc/pgpool-II/pool_passwd chown postgres:postgres /etc/pgpool-II/pool_passwd这里我用-u postgres指定了要认证的用户名密码要和 PostgreSQL 里的一致否则客户端连接时认证失败。4.6 编写 failover.sh 和 failback.sh这两个脚本是故障转移的关键。failover.sh 在主库不可用时触发它负责把备库提升为新主库并通知 pgpool 更新节点状态#!/bin/bash # $1 failed node id, $2 failed hostname, $3 failed port, # $4 failed data dir, $5 new main node id, $6 new main hostname, # $7 new main port, $8 new main data dir PGDATA_DIR/var/lib/pgsql/14/data PGBIN/usr/pgsql-14/bin LOG_FILE/var/log/pgpool/failover.log echo $(date) failover triggered: node $1 ($2:$3) failed, promote $6 $LOG_FILE if [ $1 -eq 0 ]; then # 主库挂了提升备库 ssh postgres$6 $PGBIN/pg_ctl promote -D $8 sleep 5 exit 0 fi这个脚本里有个细节没有用 pgpool 的pcp_promote_node而是直接用pg_ctl promote原因是我希望提升动作在数据库实例层面真正完成而不是只在 pgpool 状态表里标记一下。两者区别在于如果只是标记 pgpool 状态而 PostgreSQL 还没真正执行 promote那么后续写请求进来会落到一个仍处于只读状态的实例上直接报错。failback.sh 在老主库恢复后把它重新加入集群。这里只做简单记录具体的数据追平需要配合pg_rewind我会在常见问题部分详细说明#!/bin/bash # $1 failed host, $2 new main host, $3 new main port LOG_FILE/var/log/pgpool/failback.log echo $(date) failback: node $1 rejoins cluster, current main is $2 $LOG_FILE exit 0生产环境我会在 failback 脚本里加上pg_rewind的自动执行逻辑但这一步对新手来说风险较高建议先在测试环境验证好再上。5. keepalived 实现 VIP 漂移5.1 keepalived 配置pgpool 节点 1 作为 keepalived MASTER节点 2 作为 BACKUP。节点 1 的配置global_defs { router_id pgpool_master } vrrp_script check_pgpool { script /etc/keepalived/check_pgpool.sh interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass your_auth_pass } track_script { check_pgpool } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:0 } }节点 2 的配置基本一样把state MASTER改成BACKUPpriority改成90其他参数一致。5.2 健康检查脚本keepalived本身只负责VIP漂移它需要知道pgpool到底还活着没有。我写了一个简单的检测脚本#!/bin/bash if [ $(ps -ef | grep -c [p]gpool) -eq 0 ]; then exit 1 fi exit 0如果 pgpool 进程不存在keepalived的权重会降低VIP 自动漂移到另一台 pgpool 节点。这个方案的优点是简单直接缺点是只检测了进程是否存在没有检测 pgpool 是否真的能对外提供服务。更严格的检测可以加一条 TCP 连接测试比如用nc -z localhost 9999检查端口但要注意检测频率别太高否则 keepalived 会频繁抖动。6. 启动与验证6.1 启动顺序启动有个先后顺序这也是新手最容易搞混的地方先启动两台 PostgreSQL确保主备流复制正常启动两台 pgpool先主后备让 watchdog 正常建立通信启动 keepalived让 VIP 绑定到节点 1# 1. PostgreSQL节点 systemctl start postgresql-14 # 2. pgpool节点 systemctl start pgpool systemctl enable pgpool # 3. keepalived节点 systemctl start keepalived systemctl enable keepalived6.2 检查 pgpool 状态在 pgpool 节点上执行psql -h 192.168.1.100 -p 9999 -U postgres -c show pool_nodes;如果配置正确应该看到类似下面的输出node_id | hostname | port | status | lb_weight | role ----------------------------------------------------- 0 | pg-node1 | 5432 | up | 0.5 | primary 1 | pg-node2 | 5432 | up | 0.5 | standbystatus为uprole一个primary一个standby这就是理想状态。如果status显示down说明 pgpool 和后端 PostgreSQL 的健康检查失败了。再检查一下 VIP 是否生效ip addr show eth0 | grep 192.168.1.100能看到这个 IP 就说明 keepalived 工作正常。6.3 应用连接方式应用连接字符串应该指向 pgpool 的 VIP 和 9999 端口jdbc:postgresql://192.168.1.100:9999/appdb这里有个容易踩的坑应用连的是 VIP不是具体某台 pgpool也不是后端的 PostgreSQL 节点。如果应用直连了后端数据库那高可用就白搭了后端一切换应用立刻断连。7. 故障转移实测7.1 模拟主库宕机最直接的测试方法就是把主库的 PostgreSQL 进程杀掉# 在主库节点 pg-node1 上执行 pkill -9 postgres模拟的是最强故障——进程被直接杀死没有优雅退出。7.2 观察故障转移过程然后观察 pgpool 日志看故障转移是否被正确触发tail -f /var/log/pgpool/pgpool.log正常情况下会看到类似以下日志序列ERROR: failed to connect to PostgreSQL server on pg-node1:5432 LOG: health check failed on node 0 LOG: executing failover command LOG: failover: promoting node 1 to primary LOG: failover: done等几秒钟再执行psql -h 192.168.1.100 -p 9999 -U postgres -c show pool_nodes;这时候应该看到node_id 1的状态变成了primarynode_id 0变成了down。故障切换完成。7.3 应用无感验证我在测试环境跑了一个持续写入的压力脚本连接字符串指向 VIP。观察到的现象是主库宕机瞬间写入请求会报错但这个报错窗口不超过 15 秒之后新连接自动落到新主库上事务继续正常提交。如果应用层做了连接重试机制整个故障转移过程用户根本感知不到。这个 15 秒的窗口主要包含健康检查发现故障最多5秒、触发 failover 脚本几秒、pgpool 更新节点状态瞬时。如果希望窗口更短可以把health_check_period调小到 2 秒但要注意加大误判风险需要根据实际网络状况权衡。7.4 老主库恢复加入集群这是很多教程没讲清楚的部分。主库恢复之后不能直接把它启起来加回集群因为它身上已经没有新数据了而且它原来的身份是主库现在整个集群的主库已经是 pg-node2 了。直接加入会导致数据不一致。正确做法分两步先用pg_rewind让老主库追平新主库的数据再把它作为备库重新加入# 在 pg-node1 上执行pg-node2 现在是主库 /usr/pgsql-14/bin/pg_rewind --target-pgdata/var/lib/pgsql/14/data \ --source-serverhostpg-node2 port5432 userpostgres dbnamepostgres执行成功后创建 standby 信号文件touch /var/lib/pgsql/14/data/standby.signal然后修改postgresql.auto.conf添加连接新主库的信息primary_conninfo hostpg-node2 port5432 userpostgres passwordYourStrongPassword最后启动 PostgreSQLsystemctl start postgresql-14启动后pgpool 的健康检查会自动发现老主库恢复了把它加入后备节点列表。再执行show pool_nodes应该看到两个节点都是up主库是 pg-node2备库是 pg-node1。这整条链路我在生产环境验证过一次老主库从断电到重新加入集群总耗时大约 10 分钟其中大部分时间花在人工确认数据一致性上。如果数据量不大整个过程可以压缩到 5 分钟以内。8. 常见问题与排障实录8.1 pgpool 节点显示 down现象show pool_nodes里面某个节点的状态是down但 PostgreSQL 进程是正常的。排查方向确认 pgpool 健康检查使用的用户名密码正确。pgpool 是用health_check_user去连接后端数据库的密码错了会导致健康检查一直失败检查 pg_hba.conf 里是否允许 pgpool 所在 IP 连接。注意健康检查用的也是普通连接不是 replication 连接所以要在pg_hba.conf里配置对应的 host 记录检查网络连通性。用telnet或者nc从 pgpool 节点测后端数据库的 5432 端口通不通8.2 故障切换后原主库不能重新加入现象原主库通过pg_rewind同步数据后启动发现和当前主库数据还是不一致或者干脆启动失败。原因分析pg_rewind要求原主库开启了wal_log_hints on或者checksum否则它无法判断哪些数据块需要重放会报错退出。解决方案在 PostgreSQL 14 的配置里加上wal_log_hints on然后重启生效。这是我在生产环境踩过最痛的坑如果不提前开启这个参数等需要pg_rewind的时候再改必须重启数据库那就失去“无缝回归”的意义了。8.3 pgpool 脑裂现象两台 pgpool 同时绑定 VIP都认为自己才是 MASTER应用请求被随机分发到两台 pgpool 上后端的写请求可能出现冲突。排查方向检查两台 pgpool 之间的 heartbeat 通信。watchdog 使用wd_hb_interval配置的心跳包维持状态同步如果网络不通它们会彼此认为对方挂了从而同时抢占 VIP检查 keepalived 的认证配置。auth_pass不一致会导致 keepalived 节点间无法同步状态检查delegate_IP是否被其他设备占用如果这个 IP 已经绑到了别的地方两台 pgpool 都会抢不到或者一个能抢到一个不能解决思路在 keepalived 的检测脚本里增加“检查对方是否存活”的逻辑。比如本轮检测如果发现自己能 ping 通对方并且对方也在广播 VIP就主动放弃 VIP。8.4 连接数被打满现象应用侧频繁报连接超时pgpool 日志里出现sorry, too many clients already。原因分析num_init_children限制了 pgpool 可以同时接受的客户端连接数。这个值不是越大越好它的底层逻辑是每个子进程都要消耗系统资源和 PostgreSQL 的max_connections也不是一一对应的。因为 pgpool 还有连接池功能一个后端连接可以被多个客户端复用。优化建议把num_init_children调大比如 64 或者 128但前提是系统内存够确认应用端是否设置了连接池。如果应用本身有连接池比如 Java 的 HikariCP连接数应该是可控的检查是否有慢查询占用了连接池里的连接不释放。child_life_time可以限制子进程的最大存活时间让异常连接自动回收我个人推荐num_init_children设置为 2~3 倍的预期并发数再配合max_pool 4这样连接池的使用效率最高。8.5 读写分离不生效现象show pool_nodes显示两个节点都是up执行查询也确实能返回数据但所有请求都打到主库上备库没有承担任何读流量。原因分析pgpool 的负载均衡不是无条件的。它要求请求的会话不能绑定到某个后端节点同时查询不能修改数据。具体来说以下场景会导致负载均衡失效会话开启了事务且事务内没有使用只读语句查询语句被显式标记为需要路由到主库statement_level_load_balance没有开启优化配置statement_level_load_balance on开启这个参数后即使在一个会话里连续执行多条只读 SQLpgpool 也会尝试在多个节点之间分散请求。8.6 pcp 命令连接失败现象执行pcp_node_count等命令时提示认证失败。排查方向pcp 认证用的不是 PostgreSQL 的密码而是pcp.conf里的密码。确认你生成密码 MD5 时用的命令和格式正确/usr/pgpool-14/bin/pg_md5 YourPassword然后把输出追到/etc/pgpool-II/pcp.conf里格式是“用户名:MD5值”。还要注意pcp 命令默认也要走认证如果用pcp_node_count -h 127.0.0.1 -U pgpool它会提示输入密码这个密码就是pcp.conf里的那个。9. 优化与监控建议9.1 延迟与数据一致性pgpool 的负载均衡把读请求分发到备库但备库的数据和主库之间存在流复制延迟。如果业务对读一致性要求极高比如用户刚提交订单立刻查状态这种读写分离架构就会有问题。解决方案有二让这类关键读请求强制走主库。pgpool 提供了/*NO LOAD BALANCE*/注释标记应用可以在 SQL 前加这个注释pgpool 就会把这条查询路由到主库设置delay_threshold超过阈值的备库自动从负载均衡中剔除delay_threshold 1000000这个值单位是字节表示备库 WAL 日志落后主库超过 1MB 时就不再参与读负载均衡。9.2 pgpool 节点自身的监控pgpool 挂了VIP 会自动漂移但运维人员需要第一时间知道。我在生产环境里用简单的 shell 脚本 监控平台比如 Zabbix 或 Prometheus做告警。脚本核心逻辑#!/bin/bash # 检测 pgpool 是否活着 当前 VIP 是否绑定正确 pgpool_alive$(ps -ef | grep -c [p]gpool) vip_exists$(ip addr show eth0 | grep -c 192.168.1.100) if [ $pgpool_alive -eq 0 ]; then echo pgpool is down exit 1 fi if [ $vip_exists -eq 1 ]; then echo pgpool is alive, VIP present else echo pgpool is alive, but VIP not on this node fi监控的意义在于主备切换虽然自动完成了但如果你不知道发生了切换可能会在业务出现异常时找不到方向。每次切换都应该有告警让运维人员介入确认。9.3 连接池参数调优给一个我常用的参数模板参数建议值说明num_init_children64按业务预估并发数调整max_pool4每个子进程到后端的连接池大小child_life_time300300秒后回收子进程防止内存泄漏connection_life_time00表示永久有效如需定期重连可设置1800client_idle_limit0客户端空闲多少秒后断开0表示不断开参数调整不是一劳永逸的建议每隔一段时间观察 pgpool 的进程数和内存占用再结合业务高峰期的表现微调。10. 个人实践心得这套 PostgreSQL pgpool 高可用集群我从测试到生产已经维护了大半年整体稳定性是靠谱的。但有几个建议想分享给后来者第一先在测试环境完整演练至少三次故障切换包括主库宕机、备库宕机、pgpool 节点宕机、网络分区这四类场景。我在测试阶段发现过一个问题主库宕机时如果备库的 WAL 归档路径和主库不一致pg_rewind会失败。这种问题只有多演练才能暴露。第二pgpool 的配置项非常多别追求一次配到完美。先把最核心的链路走通——客户端连得上、读写分离、故障转移能切换——然后再逐项优化负载均衡策略、连接池参数、健康检查频率。一上来就想配一个“完美”的配置往往会被大量参数淹没。第三日志和监控一定要早点接入。pgpool 自身日志、系统日志、数据库日志三者缺一不可。我见过很多团队部署得好好的等到出故障了才想起来翻日志结果发现日志没配全追溯起来非常费劲。第四关于“自动恢复加入集群”我建议在运维流程里加一道“人工确认”的关卡老主库恢复后先让它作为备库加入观察半小时确认数据追平、复制延迟稳定再把它重新纳入负载均衡。不是所有故障都需要立即恢复稳定比速度更重要尤其在金融、电商这类对一致性敏感的业务里。最后说一个细节pgpool 的配置文件里到处是路径、用户名、密码改完配置一定要重启服务并确认日志里没有报错。我习惯改完配置后执行一次pgpool reload不是 restart然后看日志确认配置没有语法错误再决定是否重启。reload和restart的区别在于reload 会重新读取配置但不中断现有连接restart 会清空所有连接池。生产环境尽量用 reload减少对业务的影响。如果你正在折腾这套架构希望这篇文章能帮你少踩几个坑。有问题多观察日志多模拟故障多验证行为系统会慢慢给你答案。

相关新闻

COMSOL仿真波导BIC现象:原理与建模实践

COMSOL仿真波导BIC现象:原理与建模实践

1. 波导BIC现象初探:当电磁波遇见拓扑缺陷在电磁学领域,Bound states in the continuum(连续谱中的束缚态,简称BIC)堪称一种反直觉的物理现象。想象一下:一束光被完美地囚禁在波导结构中,即使周…

2026/10/13 16:30:49 阅读更多 →
虚拟电厂多时间尺度调度与储能容量衰减的Matlab复现

虚拟电厂多时间尺度调度与储能容量衰减的Matlab复现

提到“虚拟电厂的多时间尺度调度”,搞电力系统优化的人应该都不陌生。我复现过好几篇相关方向的高水平论文,最大的感受是:真正把储能容量衰减、发电侧调节能力和用户负荷灵活性放进同一个框架里的工作不多,而能把这个框架跑通、跑…

2026/10/13 16:30:49 阅读更多 →
JMeter性能测试实战:从脚本设计到分布式压测与报告分析

JMeter性能测试实战:从脚本设计到分布式压测与报告分析

JMeter性能测试详解,这可能是你在搜索引擎里见过最多、却很难找到一篇真正聊透的话题。我在日常工作中压过电商秒杀、直播弹幕、支付回调、文件上传,也用JMeter做过接口自动化回归,踩过的坑一只脚数不过来。这三年下来我最大的感受是&#xf…

2026/10/13 16:29:45 阅读更多 →

最新新闻

SQL WHERE语句核心语法与性能优化实战指南

SQL WHERE语句核心语法与性能优化实战指南

WHERE语句本身不难,但很多人写SQL多年还是会在它上面栽跟头——要么是条件写错导致全表扫描,要么是NULL值判断踩坑,要么是复杂的多条件组合逻辑理不清。这篇东西我把实际项目里积累的经验捋一遍,从基础语法到进阶坑点都覆盖到&…

2026/10/13 17:12:13 阅读更多 →
LiteLLM:统一LLM调用接口的跨模型抽象层实战指南

LiteLLM:统一LLM调用接口的跨模型抽象层实战指南

1. 项目概述:LiteLLM 是什么,它解决了哪些真实痛点? LiteLLM 这个名字乍一听像是某个轻量级编程语言或小众框架,但其实它是一个在开发者圈子里快速升温的开源工具——准确地说,它是一个 统一的 LLM(大语言…

2026/10/13 17:12:13 阅读更多 →
Windows 上 Claude Code 安装配置与避坑实战指南

Windows 上 Claude Code 安装配置与避坑实战指南

Claude Code 是 Anthropic 官方的命令行 AI 编程助手,在 Windows 上把它跑起来,等于给你的 PowerShell 或 Windows Terminal 装了一个能读代码、改代码、执行命令、查异常的老练结对工程师。它最大的价值是把“复制代码去网页里问”改成“直接在项目目录…

2026/10/13 17:12:13 阅读更多 →
如何识别与规避虚构技术工具的误导性内容

如何识别与规避虚构技术工具的误导性内容

我无法根据当前输入生成符合要求的博文。原因如下:项目标题 "impeccable" 本身无明确技术指向:该词为英文形容词(意为“无可挑剔的、完美的”),在技术语境中不构成可解析的项目实体。它既非工具名、框架名、…

2026/10/13 17:12:13 阅读更多 →
impeccable CLI协议:npx驱动的零配置终端交互范式

impeccable CLI协议:npx驱动的零配置终端交互范式

1. 项目概述:一个被误读的“完美”工具名,以及它背后真实的CLI生态逻辑最近在多个开发者社区和前端技术群聊里,“impeccable”这个词频繁跳出来——不是作为形容词,而是作为一个命令行工具的名字。很多人第一反应是:“…

2026/10/13 17:12:13 阅读更多 →
配电网韧性提升中的移动储能预布局与动态调度优化:IEEE33节点Matlab实现

配电网韧性提升中的移动储能预布局与动态调度优化:IEEE33节点Matlab实现

配电网韧性、移动储能预布局、动态调度,这三个词放在一起,基本就是一个典型的两阶段优化问题。这篇项目复现的是基于IEEE33节点算例的完整Matlab实现,目标很直接:在台风、冰冻这类极端灾害场景下,通过移动储能的灾前布…

2026/10/13 17:11:12 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →