当前位置: 首页 > ds >正文

【PostgreSQL】如何实现主从复制?

PostgreSQL 主从复制最简单、最常用、官方推荐的方法是流复制 (Streaming Replication)。它利用 PostgreSQL 的预写日志 (WAL, Write-Ahead Log) 进行数据同步。

这里介绍一个基于 pg_basebackupstandby.signal 的简单配置方法,适用于 PostgreSQL 12 及更高版本 (因为 standby.signal 和将 primary_conninfo 直接写入 postgresql.auto.conf 是其特点)。

核心思想:

  1. Primary (主库) 配置: 开启 WAL 日志发送功能,并允许副本连接。

  2. Replica (从库) 初始化: 使用 pg_basebackup 从主库获取一份基准备份,并自动配置为从库。

  3. Replica (从库) 启动: 启动从库服务,它会自动连接主库并开始接收 WAL 日志。


环境准备:

假设你有两台服务器(或虚拟机):

  • Primary (主库): 192.168.1.101

  • Replica (从库): 192.168.1.102

两台机器上都已安装 PostgreSQL,并且能够相互 ping 通。

第一步:Primary (主库) 配置

  1. 编辑 postgresql.conf 文件

找到你的 PostgreSQL 数据目录下的 postgresql.conf 文件 (通常在 /etc/postgresql/1X/main/postgresql.conf$PGDATA/postgresql.conf)。修改或添加以下参数:


# 允许所有IP连接(或者指定从库IP)listen_addresses = '*'# 开启WAL日志级别,`replica` 足够用于流复制wal_level = replica# 最大同时发送WAL日志的进程数(根据需要设置,一般5-10个足够)max_wal_senders = 10# 保持WAL日志文件大小,防止从库断开重连后找不到WAL日志# 生产环境中建议设置大一些,如 1GB 或更多,具体取决于WAL生成速度和网络稳定性wal_keep_size = 512MB # PostgreSQL 13及以前是 wal_keep_segments# 如果是 PostgreSQL 13 以前的版本,可能需要设置 wal_keep_segments = 32 (每个16MB,总共512MB)# 可选:开启WAL归档。对于生产环境非常重要,用于PITR (Point-In-Time Recovery) 和从库长时间掉线后的恢复。# 如果只是简单的流复制测试,可以暂时不开启,但强烈建议开启。# archive_mode = on# archive_command = 'cp %p /mnt/pg_archive/%f' # 替换为你的归档目录
  1. 编辑 pg_hba.conf 文件

允许从库以复制用户身份连接。找到你的 pg_hba.conf 文件 (与 postgresql.conf 在同一目录下),添加以下一行:


# TYPE  DATABASE        USER            ADDRESS                 METHODhost    replication     repuser         192.168.1.102/32        md5# 或者允许所有IP进行复制连接,但不推荐用于生产环境# host    replication     repuser         0.0.0.0/0               md5
  • replication 是一个特殊的“数据库”,表示复制连接。

  • repuser 是你将要创建的复制用户。

  • 192.168.1.102/32 是你的从库IP地址。

  1. 创建复制用户

postgres 用户身份连接到主库,创建用于复制的用户:


# 切换到postgres用户sudo -i -u postgres# 进入psql控制台psql# 创建复制用户CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT -1 ENCRYPTED PASSWORD 'your_secure_password';# 退出psql\q

注意: 请将 your_secure_password 替换为强密码。

  1. 重启 Primary (主库) 服务

使配置生效:


sudo systemctl restart postgresql# 或者根据你的系统和PostgreSQL版本使用相应的命令,例如:# sudo /etc/init.d/postgresql restart

第二步:Replica (从库) 初始化

  1. 停止 Replica (从库) 服务 (如果正在运行)

如果你的从库上已经有 PostgreSQL 服务在运行,请先停止它。


sudo systemctl stop postgresql
  1. 清空从库数据目录 (重要!)

警告: 这会删除从库上所有现有的 PostgreSQL 数据。请确保你清楚自己在做什么!

找到从库的 PostgreSQL 数据目录 (例如 /var/lib/postgresql/1X/main/usr/local/pgsql/data)。


# 假设数据目录是 /var/lib/postgresql/14/mainsudo rm -rf /var/lib/postgresql/14/main/*
  1. 使用 pg_basebackup 获取基准备份

切换到能够访问到 PostgreSQL 数据目录的用户 (通常是 postgres 用户),然后执行以下命令:


sudo -i -u postgres# 替换 primary_ip, repuser, your_secure_password, 和你的数据目录路径# 例如:pg_basebackup -h 192.168.1.101 -U repuser -D /var/lib/postgresql/14/main -F p -X stream -P -v -R -wpg_basebackup -h 192.168.1.101 \-U repuser \-D /var/lib/postgresql/14/main \-F p \-X stream \-P \-v \-R \-w

参数说明:

  • -h 192.168.1.101: 主库的IP地址。

  • -U repuser: 用于连接主库的复制用户。

  • -D /var/lib/postgresql/14/main: 从库的数据目录。

  • -F p: 输出格式为 “plain” (纯文件),而不是 “tar”。

  • -X stream: 在备份过程中同时流式传输 WAL 日志。

  • -P: 显示进度。

  • -v: 详细输出。

  • -R: 最重要! 自动创建 standby.signal 文件并在 postgresql.auto.conf 中添加 primary_conninfo。这是简化配置的关键!

  • -w: 提示输入密码(如果密码不在环境变量中)。

执行命令后会要求输入 repuser 的密码。

  1. 确认从库配置

pg_basebackup -R 已经帮你完成了大部分配置。你可以检查从库数据目录下是否生成了:

  • standby.signal 文件(这是一个空文件,PostgreSQL 启动时检测到它就会进入恢复模式)。

  • postgresql.auto.conf 文件中包含了 primary_conninfo 参数,类似这样:


# Do not edit this file manually!# It will be overwritten by the ALTER SYSTEM command.primary_conninfo = 'user=repuser password=your_secure_password host=192.168.1.101 port=5432 sslmode=prefer sslcompression=0 gsslib=0 channel_binding=prefer'

pg_basebackup 会自动将密码写入这个文件。在生产环境中,出于安全考虑,你可能需要手动修改 primary_conninfo,将密码从明文移除,并通过 .pgpass 文件或其他更安全的方式提供密码。但对于简单测试,这样是可以的。


第三步:启动 Replica (从库) 服务并验证

  1. 启动 Replica (从库) 服务

sudo systemctl start postgresql
  1. 验证复制状态
  • 在 Primary (主库) 上检查:

sudo -i -u postgrespsql -c "SELECT client_addr, state, sync_state, sync_priority FROM pg_stat_replication;"

你应该看到一行输出,其中 client_addr 是从库的IP,statestreamingsync_state 通常是 async (异步)。

  • 在 Replica (从库) 上检查:

sudo -i -u postgrespsql -c "SELECT pg_is_in_recovery();"

应该返回 t (true)。


psql -c "SELECT pg_last_wal_replay_lsn();"# 记录这个LSN# 在主库上运行以下命令,比较LSN,看是否接近或相同psql -h 192.168.1.101 -U postgres -c "SELECT pg_current_wal_lsn();"

pg_last_wal_replay_lsn() (从库) 应该接近或等于 pg_current_wal_lsn() (主库)。

在主库上插入一些数据,然后在从库上查询,看看数据是否同步过来。

主库:


CREATE TABLE test_repl (id INT, name TEXT);INSERT INTO test_repl VALUES (1, 'hello');SELECT * FROM test_repl;

从库:


SELECT * FROM test_repl; -- 应该能看到 'hello'-- 尝试插入数据会失败,因为从库是只读的-- INSERT INTO test_repl VALUES (2, 'world');

重要注意事项:

  • 防火墙: 确保主库的 5432 端口对从库开放,反之亦然(如果需要从从库连接到主库)。

  • WAL Archiving (WAL 归档): 虽然不是流复制的硬性要求,但在生产环境中强烈建议开启。它能让你在从库长时间掉线后通过归档日志进行恢复,也方便进行 Point-in-Time Recovery (PITR)。

  • 安全:

  • repuser 应该使用强密码。

  • pg_hba.conf 中尽可能指定从库的精确 IP 地址,而不是 0.0.0.0/0

  • primary_conninfo 中的密码最好通过 .pgpass 文件或其他方式保护,而不是明文存储在 postgresql.auto.conf 中。

  • 同步 vs. 异步: 上述配置是异步复制。这意味着主库在写入数据后不需要等待从库确认就已经提交事务。这提供了更好的性能,但可能会在主库崩溃时导致少量数据丢失。同步复制可以防止数据丢失,但会增加主库的事务延迟。

  • 高可用性: 这个配置只是实现了主从复制,不包含自动故障转移。如果主库挂了,你需要手动提升从库为主库,并配置其他从库连接到新的主库。这通常需要使用像 Patroni、PgBouncer、repmgr 或 corosync/pacemaker 等工具来构建高可用集群。

  • 版本兼容性: 本指南主要针对 PostgreSQL 12 及更高版本。对于 PostgreSQL 11 及更早版本,recovery.conf 文件扮演了 standby.signalprimary_conninfo 的角色。

这个方法是搭建 PostgreSQL 流复制最简单、最快捷的方式,非常适合初次尝试或测试环境。

http://www.xdnf.cn/news/20441.html

相关文章:

  • 网络原理-
  • 在Ubuntu平台搭建RTMP直播服务器使用SRS简要指南
  • Qt 基础教程合集(完)
  • 分布式数据架构
  • 硬件开发_基于物联网的老人跌倒监测报警系统
  • 数据结构——栈(Java)
  • MySQL数据库约束和设计
  • 附050.Kubernetes Karmada Helm部署联邦及使用
  • C++_哈希
  • 基于阿里云ECS搭建Tailscale DERP中继服务器:提升跨网络连接速度
  • 前端登录鉴权详解
  • C++面试10——构造函数、拷贝构造函数和赋值运算符
  • 西门子S7-200 SMART PLC:编写最基础的“起保停”程序
  • [特殊字符] 从零到一:打造你的VSCode圈复杂度分析插件
  • Linux内核源码获取与编译安装完整指南
  • Java8函数式编程之Stream API
  • 预闪为什么可以用来防红眼?
  • C/C++动态爱心
  • Caffeine Weigher
  • 蓓韵安禧DHA纯植物藻油纯净安全零添加守护母婴健康
  • 基于STM32智能阳台监控系统
  • Unity 如何使用ModbusTCP 和PLC通讯
  • 用 Go + HTML 实现 OpenHarmony 投屏(hdckit-go + WebSocket + Canvas 实战)
  • 《sklearn机器学习——绘制分数以评估模型》验证曲线、学习曲线
  • 鸿蒙Next开发指南:UIContext接口解析与全屏拉起元服务实战
  • DevOps实战(2) - 使用Arbess+GitPuk+Docker实现Java项目自动化部署
  • Rsyslog日志采集
  • 快捷:常见ocr学术数据集预处理版本汇总(适配mmocr)
  • js闭包问题
  • B.50.10.07-分布式锁核心原理与电商应用