PostgreSQL 16 流复制主从搭建实战:从踩坑到明白

环境:Ubuntu 22.04 × 2 · PostgreSQL 16 · 适合生产参考

上个月给项目搭主从,照着老教程一路配下来"看起来都对了",结果主库跑两天后 WAL 把磁盘撑爆,主库直接罢工。排查完才明白是复制没配防漂移,WAL 只进不出。这篇把一次配稳的完整流程和坑都写出来,你可以直接抄。

先说架构:一主一从,异步流复制(生产最常用),主库 192.168.1.10,从库 192.168.1.11,都是 PG 16。

一、主库配置:三个参数一个用户

编辑主库的 postgresql.conf

ini 复制代码
listen_addresses = '*'
wal_level = replica              # 流复制最低要求,默认就是它,确认一下
max_wal_senders = 10            # wal 发送进程上限,留点余量
max_replication_slots = 10      # 复制槽上限,后面要用

建专用复制用户(别拿超级用户跑复制):

sql 复制代码
CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'ReplPass_2026';

二、pg_hba.conf 放行复制连接

sql 复制代码
# TYPE   DATABASE   USER   ADDRESS          METHOD
host    replication repl   192.168.1.0/24   scram-sha-256

注意这行的 DATABASE 是 replication ,不是业务库名。它匹配的是复制流的专用通道,和业务连接的 host all all ... 是两回事。改完 reload 即可:SELECT pg_reload_conf();(但 listen_addresses 是 postmaster 级参数,第一次改要 restart)。

三、从库:pg_basebackup 一把梭

从库装同版本 PG 16 后,先停服务,用 pg_basebackup 从主库拉基线:

css 复制代码
sudo systemctl stop postgresql

sudo -i -u postgres

pg_basebackup -h 192.168.1.10 -U repl -D /var/lib/postgresql/16/main \
  -Fp -Xs -P -R --slot=standby1 --create-slot

参数说人话:

  • -Fp:纯文件格式,和普通数据目录一样
  • -Xs:备份期间 WAL 以流的方式同步过来,不依赖主库留旧日志
  • -R:自动生成 standby.signal 并写好 primary_conninfo,省手写
  • --slot=standby1 --create-slot:创建并绑定复制槽,防 WAL 被提前清理的关键,下面细说

确认属主后启动:

bash 复制代码
exit
sudo systemctl start postgresql

四、验证:两条命令定乾坤

主库上看发送状态:

sql 复制代码
SELECT client_addr, state, sync_state, write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

看到 state = streaming 就成了。replay_lag 是从库回放延迟,平时盯着它就知道主从落后多少。

从库上确认身份:

csharp 复制代码
SELECT pg_is_in_recovery();   -- true,说明是从库,只读

顺手验证只读 :在从库执行 CREATE TABLE t1(id int);,报 cannot execute CREATE TABLE in a read-only transaction 就是正常的------从库天生只读,别想着手工改。

五、我踩的坑,帮你提前踩了

坑1:不配复制槽,WAL 漂移撑爆主库

不用复制槽时,主库按 wal_keep_size 留 WAL。从库断线超过保留窗口后重连,只能从头再来一次 basebackup。我一开始按老教程只设了 wal_keep_size,从库断了一天,重搭。用复制槽后,主库会替从库保留未消费的 WAL,从库断了多久都能续上 ------这就是上面 --slot 的意义。但注意反向风险,见坑2。

坑2:复制槽是把双刃剑------从库长期下线,WAL 堆积照样爆盘

我那次爆盘的真正原因:复制槽 standby1 在,但从库所在机器被回收了没人管,主库一直替它留 WAL,留到磁盘 100%。所以生产上复制槽必须配监控 :盯 pg_replication_slotsactiverestart_lsn,从库确认不要了就 SELECT pg_drop_replication_slot('standby1'); 及时删。

坑3:两台机器 PG 小版本不一致

从库装的是 16.4,主库后来升到 16.6,某次重启后复制直接报版本不匹配。流复制要求主从小版本一致(大版本更不用说)。上生产前把两台的 apt 源锁到同一个版本,升级一起升。

六、再进一步的两个方向

  • 同步复制 :主库设 synchronous_standby_names='ANY 1 (standby1)',至少一台从库确认后才返回提交,防单点丢数据,代价是写入延迟。金融类场景再开,一般业务异步够用。
  • 故障切换 :手动 pg_promote() 能把从库提成主库,但生产别靠手速,上 Patroni 这类自动切换组件------正好也是 PGCCC PCP/PCM 课程里高可用模块的实操内容,想系统学的可以去看。

环境:PostgreSQL 16 on Ubuntu 22.04。命令以 PG 16 为准,15 及以前参数名略有差异(如 wal_keep_segmentswal_keep_size)。

相关推荐
渣渣盟5 小时前
误删数据之后:MySQL、PostgreSQL、Oracle三库紧急恢复完全实操手册
mysql·postgresql·oracle
程序员AlbertTu5 小时前
Linux 系统 Bug 调试操作手册
linux·postgresql·bug
Wang's Blog1 天前
PostgreSQL笔记8: 基于二八法则的基础性能调优
数据库·笔记·postgresql
茶本无香1 天前
通用报表自动化框架:Java调用Shell传参执行PostgreSQL SQL模板
java·sql·postgresql·shell
求索实验室2 天前
1368次实验证明:PostgreSQL对数据倾斜的基数估计无解——我的AI4S参赛实录
postgresql·ai编程
Wang's Blog2 天前
PostgreSQL笔记4: 市场地位、生态全景与行业应用实践
数据库·笔记·postgresql
Alex Gram2 天前
数据库同步工具PanguSync图文教程
java·mysql·postgresql·sqlserver·c#·数据库同步软件·数据库同步工具
零域码客2 天前
从 SQLite 到 PostgreSQL:轻量单机到分布式架构选型、避坑与迁移全解析
分布式·postgresql·sqlite·wal·架构设计·后端开发·数据库选型
倒流时光三十年3 天前
PostgreSQL Semi-Join(半连接)通俗讲解
数据库·postgresql