简介:面向 PostgreSQL 运维与架构人员的高可用部署文档,围绕流复制实现主备 WAL 日志实时同步,并结合 pgpool-II 完成连接池、负载均衡、读写分离与故障切换,适合需要搭建主从架构或补强数据库容灾能力的读者参考。压缩包仅含 1 个 docx,约 773KB,正文按方案说明、实践环境、客户环境准备与配置步骤组织,便于逐章查阅。内容从方案综述和同步、异步复制取舍讲起,说明二者在数据一致性与写性能之间的权衡,覆盖主库参数配置、备库初始化、pgpool-II 健康监控与切换策略、pg_rman 备份,以及软件版本、postgres 用户权限、安装目录、防火墙、SELinux、hosts、时钟同步和系统资源限制等部署细节,并给出启动与故障模拟测试思路。已有471人学习,可作为从原理到落地配置、排查部署细节的完整参考方案。
1. 一次主备搭好却连不上的翻车,让我重写了整套安装顺序
去年帮一个做报表系统的团队搭 PostgreSQL 高可用,主从流复制跑得好好的,pg_stat_replication里state是streaming,看着一切正常。结果应用连上 pgpool 之后,一半查询报all backend nodes are down,另一半读到的是旧数据。排查了大半天,问题不在 SQL,不在网络,而在于我图省事,先装 pgpool 后配流复制,pgpool 启动时后端节点还没进入可识别状态,pool_nodes里两个节点全是down。
这类翻车在 PostgreSQL 主从加 pgpool-II 的组合里非常典型。单机 PostgreSQL 装完能连上就算完事,但一旦上了双节点加中间件,链路就变成「客户端 → pgpool → 主库/备库」,任何一环的版本、标识文件、认证配置、心跳地址错一点,整个集群就装成半瘫。这份方案文档覆盖的正是这条完整链路:PostgreSQL 流复制、pgpool-II 连接池与读写分离、pg_rman 离线备份,环境以 RHEL/CentOS 为主,新老版本给了 10.3 配 pgpool-II 3.6.14、12.2 配 pgpool-II 4.1.1 两套对照。
适合谁看:手上有一台主库、准备加备库并且要读写分离的开发者;正在被 recovery.conf 到底该不该存在折磨的人;以及接手一套「能连但不知道能不能切」的老集群、需要重新验证的运维。后面按装什么、怎么装、坏了怎么救的顺序走一遍。
2. 环境先对齐:版本组合与操作系统前置配置
这套环境最常见的失败不是命令敲错,是版本组合没对齐。PostgreSQL 12 是一次硬分水岭——recovery.conf从这一版开始彻底消失,备库标识改由postgresql.conf里的standby_mode相关项和standby.signal文件共同决定。你拿一份 10.x 的教程去装 12.x,第一步复制实例就卡住,因为备库目录里根本不该有那个文件。
2.1 PostgreSQL 与 pgpool-II 的版本对照表
文档给了两套环境,我把它整理成能直接照着选的表。核心原则只有一条:主库、备库的 PostgreSQL 版本必须完全一致,pgpool-II 选对应大版本线,别混搭。
| 组件 | 旧版本方案 | 新版本方案 | 选择建议 |
|---|---|---|---|
| 操作系统 | CentOS 6.5 | CentOS 7.5 | 新部署直接上 7.x,6.x 的 systemd 与依赖源都难搞 |
| PostgreSQL | 10.3 | 12.2 | 12 及以上不再有 recovery.conf,配置思路要换 |
| pgpool-II | 3.6.14 | 4.1.1 | 跟 PostgreSQL 大版本匹配,配置文件项差异很大 |
| pg_rman | 与数据库版本对应 | 与数据库版本对应 | 版本不匹配会直接初始化失败 |
| 备库标识 | recovery.conf | standby.signal + postgresql.conf | 决定第六章走哪条分支 |
pg_rman 的版本选择是另一个高频坑。它不是独立工具,而是深度绑定 PostgreSQL 内部结构的备份工具,主库是 12.2 就必须用支持 12 的 pg_rman,用错版本初始化备份目录时直接报错退出,且错误信息很含糊。常见做法是先去确认数据库的pg_config --version,再挑对应分支。
2.2 关闭防火墙、SELinux 与网络参数
装之前先把系统层的拦路虎清掉。流复制要走 TCP 传 WAL,pgpool 还要额外的心跳和虚拟 IP 检测端口,防火墙和 SELinux 不关,现象就是主库能连、备库起不来、pgpool 后端全 down,而且日志里往往只有一句模糊的认证失败。
# 关闭防火墙并禁止开机自启 systemctl stop firewalld systemctl disable firewalld # 临时关闭 SELinux,同时改配置文件防止重启后恢复 setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 确认状态,enforcing 变成 permissive/disabled 才算生效 getenforce这里setenforce 0只管当前运行态,重启就回到 enforcing,所以必须同时改/etc/selinux/config。生产环境如果你坚持保留 SELinux,那就得为 PostgreSQL 数据目录、pgpool 运行时目录单独打策略标签,工作量不小,文档方案直接选择关闭,我一般也照这个来,先把集群跑通再谈加固。
接着是网络与主机名解析。两个节点必须能互相用主机名 ping 通,因为后续pg_hba.conf、primary_conninfo、pgpool 的backend_hostname全都要写主机名或固定 IP,写错了就是连接被拒。
# 两台节点分别设置,示例用 node1 / node2 hostnamectl set-hostname node1 # /etc/hosts 追加两行,主备都要加,保证双向解析 cat >> /etc/hosts <<'EOF' 192.168.10.11 node1 192.168.10.12 node2 EOF # 验证,两个方向都要通 ping -c 2 node2/etc/hosts这一项看着琐碎,但它是后面 SSH 免密、流复制连接、pgpool 健康检查的共同基础。地址一旦和实际网卡不一致,主库pg_hba.conf里写的网段就对不上,报错会跑到认证那一层去,非常容易被误判成密码问题。
2.3 时钟同步、sysctl 与 limit 资源分配
主备时钟不同步会让 WAL 时间戳、日志排查、pg_rman 备份恢复点全都乱套,出故障时你根本对不齐两边发生了什么。文档要求配置节点间时钟同步,最省事的做法是两边都对准同一个时间源,或者内网起一个时间服务互相校时。
# 安装并启用时间同步服务,指向内网时间服务器 yum install -y chrony sed -i 's/^server .*/server 192.168.10.1 iburst/' /etc/chrony.conf systemctl enable --now chronyd # 查看同步状态,确认已和源对上 chronyc sources -viburst让首次同步更快,避免刚开机时几十秒的偏差。接下来是内核参数,流复制和连接池对共享内存、信号量、最大文件描述符都有要求,sysctl不改,典型现象是备库启动报could not create shared memory segment,或者 pgpool 连接一多就too many open files。
# /etc/sysctl.d/99-pgsql.conf 追加关键参数 cat >> /etc/sysctl.d/99-pgsql.conf <<'EOF' kernel.shmmax = 68719476736 kernel.shmall = 4294967296 kernel.sem = 4096 2147483647 2147483646 512000 fs.file-max = 7672460 net.ipv4.ip_local_port_range = 9000 65500 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 EOF sysctl -p /etc/sysctl.d/99-pgsql.confkernel.shmmax决定单块共享内存上限,PostgreSQL 的shared_buffers调大后如果超过它,实例直接起不来;kernel.sem四个值分别是信号量单组上限、系统上限、单次操作上限、信号量总数,设小了并行查询和大量连接会互相抢资源。最后是用户级资源限制,在/etc/security/limits.conf里给 postgres 用户放开文件句柄和进程数。
# /etc/security/limits.conf 追加,限定 postgres 用户 cat >> /etc/security/limits.conf <<'EOF' postgres soft nofile 65535 postgres hard nofile 65535 postgres soft nproc 16384 postgres hard nproc 16384 EOFnofile决定单进程能开多少文件描述符,每个数据库连接、每个 WAL 段都是一次文件打开,连接池时代这个值给低了会在压测时突然爆掉。改完 limits 要重新登录才生效,用su - postgres进去ulimit -n确认,别只改不验。
3. 装 PostgreSQL:建用户、解压与初始化主备实例
前置清理干净之后,PostgreSQL 本身的安装其实不复杂,麻烦的是主备两台的用户、目录、权限、环境变量必须一模一样,任何一边手抖,后面复制实例就会失败在权限上。
3.1 创建 postgres 用户与统一安装目录
数据库不能用 root 跑,这是硬规矩。文档要求在主备两台都创建 postgres 用户并设密码,然后把下载的 PostgreSQL、pgpool-II、pg_rman 安装文件放到固定目录。
# 主备两台都执行:创建用户、设置密码 useradd postgres echo 'postgres' | passwd --stdin postgres # 建立统一的软件目录与数据目录 mkdir -p /opt/soft /opt/pgsql /data/pgdata chown -R postgres:postgres /opt/soft /opt/pgsql /data/pgdata chmod -R 755 /opt/soft # 确认属主,两台的输出必须一致 ls -ld /opt/pgsql /data/pgdata这里/opt/soft放安装包、/opt/pgsql是安装目标路径、/data/pgdata是数据目录,三者分开的好处是将来升级或重建实例时数据不受影响。权限上我一般把软件目录设 755、数据目录 700,数据目录里全是 WAL 和表文件,不能让其他用户随便进。两台的目录结构必须完全对称,否则备库pg_basebackup时的路径会和主库primary_conninfo里写的归档路径对不上。
接着装依赖包。PostgreSQL 编译或运行时依赖 readline、zlib、gcc 等,CentOS 7 下一条 yum 解决。
# 主备都装,编译与运行依赖 yum install -y gcc gcc-c++ make readline-devel zlib-devel \ openssl-devel pam-devel libxml2-devel libcurl-devel # 解压源码包到软件目录 cd /opt/soft tar -zxvf postgresql-12.2.tar.gz依赖装不全的典型报错是configure: error: readline library not found,看着像缺库,实际是缺-devel包。文档给的是源码安装路线,好处是路径可控、pg_rman 编译时也能直接找到pg_config。
3.2 编译安装与环境变量配置
编译参数不用堆太多,关键是--prefix要和后面环境变量里写的一致。
cd /opt/soft/postgresql-12.2 ./configure --prefix=/opt/pgsql --with-pgport=5432 --with-openssl make -j4 && make install # 确认安装产物 ls /opt/pgsql/bin | head--prefix是安装根路径,--with-pgport定默认端口,--with-openssl供后续加密连接使用。make -j4按核数并行编,机器核少就减到-j2,编到一半 OOM 反而是更高频的翻车。装完把环境变量写进 postgres 用户的.bash_profile,两台节点内容保持一致。
# 切到 postgres 用户,写入环境变量 su - postgres cat >> ~/.bash_profile <<'EOF' export PGHOME=/opt/pgsql export PGDATA=/data/pgdata export PATH=$PGHOME/bin:$PATH export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH export MANPATH=$PGHOME/share/man:$MANPATH EOF source ~/.bash_profile which psqlPGDATA必须显式导出,pg_ctl、pg_basebackup、pg_rman都靠它定位实例。LD_LIBRARY_PATH少了会在运行 pgpool 时找不到libpq,报error while loading shared libraries,这类错误信息完全没提 PostgreSQL,新手很容易往系统库方向查错。
3.3 主库初始化与启动验证
主库先初始化。initdb的参数决定字符集和校验方式,初始化之后再改代价极大,这两项在装之前就要定好。
# 主库执行初始化,指定编码与本地化 initdb -D /data/pgdata -E UTF8 --locale=C -U postgres # 启动主库实例 pg_ctl -D /data/pgdata -l /data/pgdata/startup.log start # 验证是否真的起来了 psql -c "select version();"-E UTF8是编码,--locale=C避免排序规则在不同节点上出现差异,这一点在主备环境里很重要——排序规则不一致,同一个查询在两台可能返回不同顺序,读写分离时应用会以为数据错乱。启动日志我习惯单独落到startup.log,出问题第一眼看它,比翻系统日志快。psql能返回版本号,主库这半边就算立住了。
4. 配置流复制:主库参数、备库克隆与 12.x 的标识变更
这一章是整篇文章最容易翻车的地方,也是最值得慢下来的地方。流复制的本质是主库把 WAL 通过 TCP 推给备库,备库的walreceiver收下来写本地,startup进程再重放。配置上要打通三件事:主库允许备库连、主库愿意发 WAL、备库知道自己是备库。
4.1 主库 postgresql.conf 与 pg_hba.conf
先配 SSH 免密,后面pg_basebackup和运维脚本都要用,早配早省事。
# postgres 用户下执行,两台互信 ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ssh-copy-id postgres@node2 ssh postgres@node2 "hostname"-N ''表示空密码,方便脚本调用;最后一条命令能打印出 node2 的主机名,说明免密通了。不通就是authorized_keys权限问题,.ssh目录必须 700、authorized_keys必须 600。
接下来改主库配置。以下是 12.x 的关键项,10.x 大部分相同,差在备库标识。
# 主库 postgresql.conf 需要调整的项 wal_level = replica max_wal_senders = 10 wal_keep_segments = 512 hot_standby = on synchronous_commit = on synchronous_standby_names = 'node2' listen_addresses = '*'wal_level = replica是流复制的最低要求,它保证 WAL 里包含备库重放所需的信息;max_wal_senders是并发发送 WAL 的连接数,给 10 够用,压测场景可以再高;wal_keep_segments决定主库保留多少旧 WAL 段,备库短暂断连时靠它续上,设太小会直接导致备库落后太多无法追平,只能重做基础备份;synchronous_commit = on配合synchronous_standby_names就打开了同步复制。这里有个取舍:改成同步复制后,每次事务提交都要等备库确认,写延迟会明显上升,如果业务对写入延迟敏感,就保持异步,接受主库崩溃时可能丢最后几秒数据。
访问控制文件同样必须改,不然备库连过来直接被拒。
# 主库 pg_hba.conf 追加,允许备库与本地连接 host replication all 192.168.10.0/24 md5 host all all 192.168.10.0/24 md5 local all all trust第一行专给复制连接,第二行给普通业务连接,网段要和你实际网卡一致。改完pg_ctl reload让配置生效,然后建一个复制专用账号。
-- 主库执行,创建复制用户 CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'repl_pass';REPLICATION是专用权限,比给超级用户安全得多。常见错误是建了普通账号然后pg_basebackup报权限不足,错误信息只说连接被拒,看不出是权限类型不对。
4.2 用 pg_basebackup 克隆备库并区分版本标识
备库不需要initdb,直接从主库拉一份基础备份,这是最稳的做法。差别就在版本分支上。
# 12.x 备库执行:直接克隆,-R 自动写 standby.signal 和 primary_conninfo pg_basebackup -h node1 -D /data/pgdata -U repl -F p -X stream -P -R # 10.x 备库执行:克隆后手工准备 recovery.conf pg_basebackup -h node1 -D /data/pgdata -U repl -F p -X stream -P-F p是普通文件格式,-X stream表示 WAL 随备份流一起传,-P显示进度,-R是 12.x 的关键参数,它会自动生成standby.signal并把primary_conninfo写进postgresql.conf。10.x 没有-R,要自己写recovery.conf:
# 仅 10.x:在备库数据目录创建 recovery.conf cat > /data/pgdata/recovery.conf <<'EOF' standby_mode = 'on' primary_conninfo = 'host=node1 port=5432 user=repl password=repl_pass' trigger_file = '/data/pgdata/trigger' EOF chown postgres:postgres /data/pgdata/recovery.confprimary_conninfo里的账号密码和主机名必须和主库实际一致,trigger_file是手动提升备库用的标记文件。12.x 用户完全不需要这个文件,反而要注意:如果备库目录里残留了recovery.conf,实例启动会直接报错拒绝,这是版本迁移时最隐蔽的坑。
4.3 启动备库并检查复制状态
启动顺序别搞反,先主后备,等主库pg_isready返回正常再动备库。
# 备库启动实例 pg_ctl -D /data/pgdata -l /data/pgdata/standby.log start # 主库查看复制状态 psql -c "select client_addr, state, sync_state, sent_lsn, replay_lsn from pg_stat_replication;"这条查询是判断流复制成没成的唯一标准。state必须是streaming,sync_state在同步模式下是sync,异步是async。如果查不到任何行,说明备库根本没连上,去备库看日志,最常见的是primary_conninfo里密码错或pg_hba.conf没放行。如果state是catchup,说明正在追 WAL,等一会儿就会转streaming,只要replay_lsn在往前推进就正常。
再在备库验证一下只读和延迟:
# 备库执行,确认可读且处于恢复状态 psql -c "select pg_is_in_recovery();" psql -c "select now() - pg_last_xact_replay_timestamp() as delay;"pg_is_in_recovery()返回t才是备库,返回f说明它已经变成独立主库了。delay是回放延迟,通常几毫秒到一两秒,如果持续变大,多半是网络或备库 IO 跟不上。
5. pgpool-II 安装配置:连接池、读写分离与健康检查
流复制通了之后,pgpool-II 才登场。它夹在客户端和数据库之间,负责连接池复用、把 SELECT 分发到备库、探测后端节点健康状态,以及在主库挂掉时配合脚本做故障转移。它的配置文件项多,但真正决定能不能跑通的就那几组。
5.1 安装 pgpool-II 与注册 SQL 函数
pgpool-II 依赖 PostgreSQL 的客户端库,编译时要用--with-pgsql指向 PostgreSQL 安装路径。
cd /opt/soft/pgpool-II-4.1.1 ./configure --prefix=/opt/pgpool --with-pgsql=/opt/pgsql make -j4 && make install--with-pgsql是关键,指错了会编出连不上数据库的二进制。装完要把 pgpool 的库路径加进环境变量,并且要把它的扩展函数注册到主库。
# postgres 用户环境变量追加,主备都加 export PGHOME_POOL=/opt/pgpool export PATH=$PGHOME_POOL/bin:$PATH export LD_LIBRARY_PATH=$PGHOME_POOL/lib:$LD_LIBRARY_PATH # 在主库注册 pgpool 需要的函数 psql -f /opt/pgpool/share/pgpool-II-4.1.1/health_check_2nd.sql5.2 pgpool.conf 的三个核心区段
配置文件分三块看:连接池与后端节点、读写分离、健康检查与故障转移。以下是新版本的关键项。
# pgpool.conf 关键项 listen_addresses = '*' port = 9999 backend_hostname0 = 'node1' backend_port0 = 5432 backend_weight0 = 1 backend_flag0 = 'ALWAYS_PRIMARY' backend_hostname1 = 'node2' backend_port1 = 5432 backend_weight1 = 1 backend_flag1 = 'DISALLOW_TO_FAILOVER'backend_flag决定故障转移行为。ALWAYS_PRIMARY告诉 pgpool 这个节点固定当主库,DISALLOW_TO_FAILOVER表示备库不做提升规避,保证主备角色稳定不乱。backend_weight是读请求权重,两台都设 1 就是均分。
# 读写分离与健康检查 load_balance_mode = on master_slave_mode = on master_slave_sub_mode = 'stream' health_check_period = 10 health_check_timeout = 20 health_check_user = 'pgpool_check' health_check_password = 'check_pass' failover_command = '/opt/pgpool/bin/failover.sh %d %H'load_balance_mode = on打开读写分离,pgpool 会把不在事务里的 SELECT 发到备库,写和事务内的查询走主库。master_slave_sub_mode = 'stream'明确告诉它底层是流复制,这决定它判断主备身份的方式。health_check_period是健康检查间隔秒数,10 秒一次比较均衡;health_check_timeout给 20 秒,避免网络抖动误判。健康检查账号要在两台数据库都建好,否则节点会被误标为 down。failover_command里%d是失效节点编号,%H是新主库主机名。
5.3 认证文件与运行时目录
pgpool 有自己的认证层,pool_hba.conf管客户端怎么连它,pool_passwd管数据库密码怎么存。
# 生成 pool_passwd,为 postgres 用户写入密码 pg_md5 --md5auth -u postgres -p # 按提示输入密码,自动写入 pool_passwd # pool_hba.conf 放行客户端网段 echo "host all all 192.168.10.0/24 md5" >> /etc/pgpool/pool_hba.conf # 创建运行时目录,pgpool 的 pid 和状态文件都放这 mkdir -p /var/run/pgpool chown -R postgres:postgres /var/run/pgpoolpool_passwd里存的是 MD5 后的密码,客户端连 pgpool 时由它做第一道认证,认证过了再用配置里的账号连后端。运行时目录不建,pgpool 启动会报could not create pid file,这个错误跟数据库一点关系都没有,却很常见。
5.4 启动 pgpool 并连接测试
启动顺序是先数据库后 pgpool,pgpool 起来后要立刻验证节点状态。
# 主备两台分别启动 pgpool pgpool -n -D > /var/log/pgpool/pgpool.log 2>&1 & # 查看节点状态 psql -h node1 -p 9999 -c "show pool_nodes;"show pool_nodes输出里每个节点有status、role两列,status必须是up,role一台primary一台standby。如果显示down,先看 pgpool 日志里健康检查的报错,九成是健康检查账号密码不对,或者后端节点的pg_hba.conf没放行 pgpool 所在地址。psql -h node1 -p 9999走的才是 pgpool 的 9999 端口,直接连 5432 测不出问题。
6. 避坑记录:这套组合最常见的五个翻车点
下面几条是我和同行在这套环境里真实踩过的,每条按现象、原因、解决写,对号入座比查文档快。
第一个:备库启动直接失败,日志一句recovery.conf相关报错。现象是 12.x 备库pg_ctl start立刻退出。原因是升级或沿用了旧教程,备库目录里留了recovery.conf,12.x 已废弃该文件,存在即报错。解决是先删掉它,确认standby.signal存在,并且postgresql.conf里有正确的primary_conninfo。
第二个:show pool_nodes两个节点全 down。现象是客户端报all backend nodes are down。原因通常有两个:健康检查账号没建或密码错;或者 pgpool 启动时后端还没就绪,配置又不允许自动重连。解决是先确认health_check_user能在两台库上正常登录,再重启 pgpool 观察日志,而不是反复重启数据库。
第三个:no pg_hba.conf entry for host。现象是备库或 pgpool 连数据库被拒。原因是pg_hba.conf里写的网段和实际地址不符,或者只加了普通连接忘了复制专用行。解决是对照实际 IP 逐一补齐,host replication那行单独检查,改完reload而不是restart。
第四个:同步复制打开后写入变慢,压测直接超时。现象是事务提交响应时间翻倍。原因是synchronous_commit = on且备库回放跟不上,主库的每次提交都在等确认。解决是评估业务能否接受异步,能接受就把synchronous_commit改回off,或者只保留remote_write级别;不能接受就先把备库 IO 和网络调好。
第五个:故障切换测试时虚拟 IP 没漂移。现象是主库进程停了,pgpool 检测到但客户端连的还是旧地址。原因是 watchdog 和虚拟 IP 相关配置不完整,或者failover_command脚本没有执行权限。解决是按日志顺序检查 watchdog 状态、脚本权限和 ip 漂移命令的实际执行结果,别只看 pgpool 有没有报错。
7. 装完怎么验证:从模拟宕机到备份恢复的收尾动作
环境跑起来不等于高可用成立。我的习惯是装完必须走一遍验证清单,验证不通过就当没装完。下面这套动作,覆盖主从、pgpool 负载、故障切换和备份恢复四层。
第一步,确认复制是活的而不是假活:
# 主库写一条,立即到备库查 psql -h node1 -p 5432 -c "create table if not exists t_verify(id int, ts timestamp); insert into t_verify values(1, now());" psql -h node2 -p 5432 -c "select * from t_verify;" # 主库看复制状态 psql -h node1 -p 5432 -c "select state, sync_state, replay_lsn from pg_stat_replication;"备库能查到刚插入的行,且state为streaming,说明数据链路是通的。这一步不要省略,有时候备库能查表只是因为基础备份里有旧数据,实际复制早就断了。
第二步,确认读写分离真的在分发:
# 连续多次走 pgpool 执行读,观察是否落到备库 for i in $(seq 1 20); do psql -h node1 -p 9999 -c "select inet_server_addr();" -t done | sort | uniq -cinet_server_addr()返回的是实际处理查询的数据库地址,正常情况下应该看到主库和备库的地址都出现。如果全是同一个地址,检查load_balance_mode是否打开、查询是否被包在事务里——事务内的 SELECT 一律走主库。
第三步,模拟主库宕机,验证切换:
# 停掉主库数据库进程 pg_ctl -D /data/pgdata stop -m fast # 观察 pgpool 日志与节点状态 psql -h node1 -p 9999 -c "show pool_nodes;"停主库进程后,pgpool 的健康检查会在一个周期内发现异常并触发failover_command。show pool_nodes里原主库变成down,备库角色应被提升。这里要提醒一句,切换成功只代表探测和脚本有效,应用端连接串必须能容忍重连,否则数据库切换了应用还在用旧连接池。
第四步,验证 pg_rman 备份能恢复。备份不是有文件就算数,要能恢复到某个时间点。
# 初始化备份目录并做一次全备 pg_rman init -B /data/pgrman -D /data/pgdata pg_rman backup -B /data/pgrman -D /data/pgdata -b full pg_rman validate -B /data/pgrman # 查看备份列表 pg_rman show -B /data/pgrman-b full是全量备份,validate校验备份文件完整性,show列出可用备份。pg_rman依赖归档模式,在postgresql.conf里要打开archive_mode = on并配好archive_command,否则备份出来的东西没法做时间点恢复。备份做完了,挑一台恢复环境实际restore一次,能起来、数据在,才算这层验证过关。
| 验证层级 | 检查命令 | 通过标准 |
|---|---|---|
| 流复制 | select state from pg_stat_replication | 返回 streaming |
| 只读查询 | 备库select * from t_verify | 能查到主库新写入数据 |
| 读写分离 | inet_server_addr()多次采样 | 主备地址都出现 |
| 故障切换 | 停主库后show pool_nodes | 原主库 down,备库提升 |
| 备份恢复 | pg_rman show与恢复演练 | 备份可校验、能恢复启动 |
这套清单我每次部署完都强制走一遍,尤其是最后一项恢复演练,很多人备了半年从没恢复过,真出事才发现归档断了。从那以后我每次上这套组合,都把「停一次主库、恢复一次备份」写进交付步骤里,不跑完不算交。希望帮到你。
本文还有配套的精品资源,点击获取