PostgreSQL主从复制实战指南:消除单点故障,附带主备切换与延迟监控命令详解
《PostgreSQL流复制配置指南:从主从搭建到故障切换》摘要 本文详细介绍了PostgreSQL流复制的配置方法,帮助用户构建高可用数据库架构。主要内容包括:流复制基于WAL日志实现主从同步的原理;环境准备要求(建议PG14+版本、独立IP地址);主库配置关键参数(wal_level、max_wal_senders等)和复制账号创建;备库通过pg_basebackup初始化数据的步骤;通过pg
现在很多企业应用都特别依赖数据库能不能一直正常跑,而 PostgreSQL 是一个功能强大又免费的关系型数据库,它自带的流复制(Streaming Replication)功能可以让我们轻松搭起一套主从结构,这篇文章会手把手教你从零开始配置,并告诉你主库挂了怎么切到备库,以及怎么检查两边数据是不是同步得及时。
一、流复制基本原理
PostgreSQL 的流复制是靠 WAL(也就是预写日志)来实现的,主库每做一次写操作就会生成对应的日志,然后实时把这些日志发给备库,备库收到后就按顺序重新执行一遍,这样两边的数据就能保持一致,这种做法不仅能起到备份作用,还能把读请求分给备库处理,从而减轻主库的压力。
说明:本文用的是 PostgreSQL 14 或更新的版本,适合常见的 Linux 系统,比如 CentOS、Ubuntu 这些。
二、实验环境准备
- 主库 IP:192.168.1.10
- 备库 IP:192.168.1.11
- 两边装的 PostgreSQL 版本要完全一样(建议至少用 14 或更高)
- 两台机器之间网络要通,防火墙不能拦住 5432 端口
三、主库端配置步骤
1. 先建一个专门用来做数据同步的账号
CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'your_secure_password';
2. 打开 postgresql.conf 文件(一般在 /var/lib/pgsql/14/data/postgresql.conf 或 /etc/postgresql/14/main/postgresql.conf),把下面几个参数改一下:
wal_level = replica
max_wal_senders = 10
hot_standby = on
listen_addresses = '*'
3. 再去 pg_hba.conf 里加一行规则,允许备库连过来拉日志
# TYPE DATABASE USER ADDRESS METHOD
host replication repl_user 192.168.1.11/32 md5
4. 改完之后重启一下 PostgreSQL 服务让设置生效
sudo systemctl restart postgresql-14
四、备库端初始化配置
1. 先停掉备库的服务,然后清空原来的数据目录
sudo systemctl stop postgresql-14
sudo rm -rf /var/lib/pgsql/14/data/*
2. 接着用 pg_basebackup 命令从主库把整个数据拷过来
sudo -u postgres pg_basebackup \
-h 192.168.1.10 \
-U repl_user \
-D /var/lib/pgsql/14/data \
-P -v -R -X stream
这里 -R 会自动创建 standby.signal 文件,并把主库地址写进 postgresql.auto.conf,而 -X stream 表示直接用流的方式传日志,不用临时存文件。
3. 最后启动备库服务
sudo systemctl start postgresql-14
这时候备库会以只读模式启动,并开始接收主库发来的日志进行同步。
五、检查复制是不是在正常工作
在主库上查一下有没有备库连上来:
SELECT * FROM pg_stat_replication;
如果看到一条记录,而且 state 字段是 streaming,那就说明连接没问题。
在备库上确认自己是不是处于备用状态:
SELECT pg_is_in_recovery(); -- 返回 true 就表示当前是备机
六、主库出问题了怎么办?手动把备库变成主库
万一主库宕机了,你可以手动把备库提升成新的主库:
方法一:直接用 pg_ctl promote 命令
sudo -u postgres pg_ctl promote -D /var/lib/pgsql/14/data
方法二:创建一个触发文件(前提是你提前在配置里指定了 promote_trigger_file)
touch /tmp/promote.trigger
注意:一旦完成提升,原来的主库就不能自动变回备库了,需要你重新配置它去连新的主库。
七、怎么知道两边数据同步有没有慢下来
1. 可以对比两边的 WAL 位置(单位是字节)
-- 在主库运行
SELECT pg_current_wal_lsn();
-- 在备库运行
SELECT pg_last_wal_replay_lsn();
两个值相减,就是还没同步过去的日志量。
2. 更直观的是看时间差
-- 在备库运行
SELECT
now() - pg_last_xact_replay_timestamp() AS replication_delay;
如果结果是 00:00:00,说明完全跟上了;如果是 00:01:20,就代表慢了 1 分 20 秒。
3. 还可以查 WAL 接收器的状态
SELECT * FROM pg_stat_wal_receiver;
这个视图会显示最后收到日志的时间、连接是否正常等信息,方便排查问题。
八、容易碰到的问题和实用建议
- 网络偶尔断一下:备库通常能自己重连,只要主库还没删掉那些还没同步完的日志文件,就能继续接着同步。
- 延迟特别大:可能是网络带宽不够、磁盘写入太慢,或者主库负载太高。
- 上线前的小建议:
- 如果业务要求数据绝对不能丢,可以把
synchronous_commit设成remote_apply,不过这样写入速度会变慢 - 推荐搭配 Patroni 加 etcd 这类工具,能自动检测故障并完成切换
- 给复制延迟设个告警阈值,比如超过 10 秒就发通知,这样能早点发现问题
- 如果业务要求数据绝对不能丢,可以把
结语
利用 PostgreSQL 自带的流复制功能,我们能很快搭出一套防止单点失效的主从系统,再配合本文提到的切换方法和监控手段,遇到故障时就能快速恢复服务,保证业务不中断。
再提醒一句:主从复制只是高可用的基础,真正在生产环境用的时候,最好加上 Patroni 或 repmgr 这样的管理工具,让整个流程更自动化、更省心。
欢迎大家在评论区留言,分享你的实际经验或者遇到的难题!
更多推荐
所有评论(0)