0

0

PostgreSQL流复制数据源配置_PostgreSQL流复制数据源建立

爱谁谁

爱谁谁

发布时间:2025-09-14 17:42:01

|

565人浏览过

|

来源于php中文网

原创

流复制通过主库发送WAL日志、备库接收并应用实现数据同步。需配置主库wal_level、max_wal_senders、pg_hba.conf允许复制连接,使用pg_basebackup创建基础备份,备库启用hot_standby并启动服务;验证通过pg_stat_replication和pg_is_in_recovery()检查状态,注意网络、权限、WAL保留策略及磁盘空间。

postgresql流复制数据源配置_postgresql流复制数据源建立

在PostgreSQL的世界里,流复制(Streaming Replication)无疑是构建高可用和数据冗余基石的关键技术。简单来说,它就是让你的数据有一个或多个实时备份,以防不测,或者分担读请求的压力。配置和建立流复制数据源,核心就在于主库(Primary)和备库(Standby)之间,通过传输和应用预写日志(WAL)来达到数据同步的目的。

说实话,第一次接触流复制,光是看着那些配置参数就有点头大。但一旦理解了背后的逻辑,其实也就那么回事。核心在于让主库知道它需要发送WAL日志,让备库知道它需要接收并应用这些日志。整个过程可以粗略分成几步,每一步都有其考量。

解决方案

配置和建立PostgreSQL流复制数据源,通常涉及主库的准备、基础备份的创建以及备库的配置启动。

1. 主库(Primary)配置

首先,我们需要调整主库的一些参数,使其能够支持流复制。这主要在

postgresql.conf
pg_hba.conf
文件中进行。

  • 修改

    postgresql.conf

    • wal_level = replica
      :这是最基础的,它告诉PostgreSQL生成足够的WAL信息以支持流复制。在旧版本中可能是
      hot_standby
      logical
      ,但
      replica
      是当前推荐的。
    • max_wal_senders = 10
      :这个参数定义了主库最多可以同时支持多少个备库连接来传输WAL。根据你的需求和备库数量设置一个合理的值,比如5-10个通常足够。
    • wal_keep_size = 5GB
      :这决定了主库在
      pg_wal
      目录下保留多少WAL文件,以供备库在需要时拉取。如果备库因为网络或其他原因短暂掉线,这些保留的WAL文件可以帮助它追赶进度。这个值需要根据你的WAL生成速度和备库的掉线容忍度来估算,太大浪费空间,太小容易导致备库无法追赶。
    • listen_addresses = '*'
      : 确保主库监听所有网络接口,这样备库才能连接上来。或者指定具体的IP地址。
    • hot_standby = on
      : 虽然这个参数主要在备库上起作用,但为了完整性,有时在主库上也会提及,不过它对主库本身的功能影响不大。
    # postgresql.conf (Primary)
    wal_level = replica
    max_wal_senders = 10
    wal_keep_size = 5GB # 或者根据实际情况调整
    listen_addresses = '*'
  • 修改

    pg_hba.conf

    • 添加一行允许备库连接到主库进行复制的规则。这通常是针对
      replication
      数据库用户。
    • 例如,如果你的备库IP是
      192.168.1.100
      ,且你打算使用一个名为
      repl_user
      的用户进行复制:
    # pg_hba.conf (Primary)
    host    replication     repl_user       192.168.1.100/32        md5

    请确保

    repl_user
    在主库中已创建,并且拥有
    replication
    权限。

  • 重启主库: 所有配置更改后,需要重启PostgreSQL服务以使之生效。

2. 创建基础备份(Base Backup)

在主库配置完成后,我们需要从主库创建一个完整的数据备份,作为备库的起点。这个过程通常使用

pg_basebackup
工具来完成。

  • 在备库机器上执行: 选择一个空目录作为备库的数据目录,然后运行

    pg_basebackup
    命令。

    # 假设备库数据目录是 /var/lib/postgresql/14/main_standby
    # -h: 主库地址
    # -p: 主库端口
    # -U: 复制用户
    # -D: 备库数据目录
    # -Fp: plain格式,非tar
    # -Xs: streaming模式,复制WAL日志
    # -R: 自动生成 recovery.conf (或 standby.signal 和 postgresql.auto.conf)
    pg_basebackup -h  -p 5432 -U repl_user -D /var/lib/postgresql/14/main_standby -Fp -Xs -R

    执行此命令时,会提示输入

    repl_user
    的密码。成功后,备库数据目录下会包含主库的完整数据,以及一个
    standby.signal
    文件(PostgreSQL 12及更高版本)或
    recovery.conf
    文件(旧版本),用于指示备库启动时进入恢复模式。

3. 备库(Standby)配置与启动

  • 修改

    postgresql.conf
    (备库):

    • hot_standby = on
      :如果希望备库在复制的同时,也能接受只读查询,这个参数必须打开。
    • primary_conninfo = 'host= port=5432 user=repl_user password='
      :这个连接字符串告诉备库如何连接到主库。
    • restore_command = 'cp /path/to/archive/%f %p'
      :如果你同时启用了WAL归档,并且希望备库在流复制中断时能从归档中恢复,就需要配置这个。但对于纯流复制,通常不是必需的。
    # postgresql.conf (Standby)
    hot_standby = on
    # primary_conninfo 通常由 pg_basebackup -R 自动生成在 postgresql.auto.conf 中,
    # 但你也可以手动添加或修改。
    # primary_conninfo = 'host= port=5432 user=repl_user password='

    请注意,

    pg_basebackup -R
    选项会自动在备库数据目录下的
    postgresql.auto.conf
    文件中生成
    primary_conninfo
    ,通常无需手动设置。

    MagickPen
    MagickPen

    在线AI英语写作助手,像魔术师一样在几秒钟内写出任何东西。

    下载
  • 启动备库: 启动备库的PostgreSQL服务。它会自动读取

    standby.signal
    recovery.conf
    ,并尝试连接主库进行WAL日志的同步和应用。

    systemctl start postgresql-14 # 或你的PostgreSQL服务名

流复制的核心原理是什么?为什么我们需要它?

这事儿听起来简单,但背后的原理其实挺精妙的。WAL日志,你可以理解为数据库的所有变更记录,它保证了数据的一致性和持久性。PostgreSQL在任何数据写入磁盘之前,都会先将这些变更写入到WAL日志中。流复制,就是把这些日志实时地从主库“快递”到备库,备库再按顺序“播放”这些变更,将其应用到自己的数据文件中。这个过程是物理级别的复制,效率很高。

至于为什么我们需要它,除了显而易见的数据安全,还有几个关键点:

  • 高可用性(High Availability):这是最主要的驱动力。如果主库突然挂了,备库可以迅速地被提升为新的主库,大大减少了业务中断的时间。这就像给你的核心业务数据买了一份实时保险。
  • 读扩展(Read Scaling):当你的应用读请求远超写请求时,可以将部分只读查询分流到备库上执行,从而减轻主库的压力,提高整体系统的吞吐量。不过,这需要应用程序层面的支持,能区分读写请求。
  • 灾难恢复(Disaster Recovery):如果整个数据中心发生灾难,只要你的备库位于不同的地理位置,就能提供快速的恢复能力。
  • 数据分析/报告:有时,我们会在备库上运行一些耗时的数据分析或报告生成任务,避免这些任务影响主库的性能。

对我来说,流复制不仅仅是一个技术配置,它更是一种风险管理策略。尤其是在生产环境中,没有流复制的数据库,就像走钢丝没有安全网,心里总是不踏实。

配置流复制时,有哪些常见的“坑”和注意事项?

我个人觉得,流复制最容易出问题的地方往往不是配置本身,而是对细节的忽略和环境的差异。比如网络延迟,有时能把人折腾疯。还有WAL日志的管理,这绝对是个重灾区。

  1. 网络连接与防火墙:这是最基础也最容易被忽视的问题。主备库之间必须能够互相访问,特别是主库的5432端口。防火墙规则(如
    ufw
    firewalld
    )一定要正确配置,允许复制用户从备库IP连接。我遇到过几次,就是因为防火墙没开通,排查了半天才发现。
  2. wal_keep_size
    的设置
    :这个参数非常关键。如果备库因为网络波动、机器重启等原因暂时掉线,它会尝试从主库拉取缺失的WAL文件。如果主库因为
    wal_keep_size
    设置太小,已经清除了备库需要的WAL文件,那么备库就无法追赶,只能重新做一次基础备份。这是一个很常见的“坑”。所以,
    wal_keep_size
    要结合你的WAL生成速度和备库的掉线容忍度来设置,或者配合WAL归档(
    archive_mode
    )使用,让备库可以从归档中获取历史WAL。
  3. pg_hba.conf
    权限问题
    :复制用户必须有正确的权限,并且在
    pg_hba.conf
    中有对应的
    replication
    规则。如果这里配置错了,备库根本连不上主库。
  4. 用户权限与密码:复制用户(如
    repl_user
    )必须在主库上创建,并拥有
    replication
    权限。密码也要确保正确,并且在
    primary_conninfo
    中配置无误。
  5. 磁盘空间:备库需要和主库一样甚至更多的磁盘空间来存储数据和WAL日志。如果备库磁盘满了,复制就会停止。
  6. PostgreSQL版本一致性:强烈建议主备库使用完全相同的PostgreSQL版本,包括小版本号。虽然有时大版本之间在一定条件下也能复制,但为了避免不必要的兼容性问题,最好保持一致。
  7. 时区与系统时间:主备库的系统时间最好同步,并使用相同的时区设置,这有助于日志分析和事件关联。
  8. 故障切换(Failover):很多人只关注了如何搭建流复制,却忽略了当主库真正挂掉时,如何安全、有效地将备库提升为主库。这需要一套成熟的故障切换策略和工具(如
    pg_auto_failover
    ,
    Patroni
    等),以及应用程序如何感知新的主库地址。单纯的手动提升备库为主库,操作不当可能会导致数据丢失或脑裂。

如何验证流复制是否正常工作,以及故障排查的初步思路?

配置完流复制,别以为就万事大吉了。最关键的是要确认它真的在工作,而且是健康地工作。我见过太多次,配置好了,但一检查发现备库早就掉队了,或者干脆就没连上。所以,定期的检查和一套初步的排查思路是必不可少的。

验证流复制状态:

  1. 在主库上检查

    pg_stat_replication
    视图: 这是最直接的检查方式。连接到主库,执行:

    SELECT client_addr, state, sync_state, sync_priority, replay_lag, write_lag, flush_lag FROM pg_stat_replication;
    • client_addr
      :应该显示备库的IP地址。
    • state
      :应该是
      streaming
      ,表示正在实时传输WAL。
    • sync_state
      :如果是同步复制,会显示
      sync
      ;如果是异步复制,则显示
      async
    • replay_lag
      :这个非常重要,表示备库落后主库多少时间。理想情况下应该非常小,接近0。如果持续增大,说明备库跟不上了。
  2. 在备库上检查

    pg_is_in_recovery()
    连接到备库,执行:

    SELECT pg_is_in_recovery();

    如果返回

    t
    (true),说明备库正在恢复模式,即正在进行流复制。如果返回
    f
    ,说明它已经脱离恢复模式,可能已经提升为主库,或者复制失败。

  3. 检查数据库日志文件: 主备库的PostgreSQL日志文件(通常在数据目录的

    log
    文件夹下)会记录复制相关的事件和错误信息。查看这些日志是排查问题的第一步。例如,主库日志会记录备库的连接信息,备库日志会记录它尝试连接主库和应用WAL的情况。

  4. 写入测试数据并验证: 如果备库设置为

    hot_standby = on
    ,你可以在主库上插入一条数据,然后在备库上立即查询,看是否能查到。这是最直观的验证方法。

故障排查的初步思路:

当发现流复制不正常时,可以按照以下步骤进行排查:

  1. 网络连通性检查: 首先确认主备库之间网络是否畅通。从备库

    ping
    主库IP,或者用
    telnet  5432
    检查端口是否开放。防火墙问题往往在这里暴露。

  2. 主库

    pg_hba.conf
    和用户权限: 检查主库的
    pg_hba.conf
    是否允许备库IP的
    replication
    用户连接。同时确认
    repl_user
    是否存在且密码正确。

  3. 主库

    postgresql.conf
    参数: 确认
    wal_level = replica
    max_wal_senders
    是否配置正确,并且主库已重启生效。

  4. 备库日志文件: 仔细查看备库的PostgreSQL日志。它通常会告诉你为什么连接不上主库,或者为什么无法应用WAL。常见的错误信息包括“could not connect to server”、“FATAL: password authentication failed”、“WAL segment xxx not found”等。

  5. wal_keep_size
    或 WAL归档问题: 如果备库日志显示“WAL segment xxx not found”,这通常意味着备库落后太多,主库已经清理了它需要的WAL文件。这时候你可能需要:

    • 增大主库的
      wal_keep_size
    • 如果启用了WAL归档,检查归档是否正常工作,以及备库的
      restore_command
      是否正确。
    • 最坏的情况,可能需要重新做一次基础备份。
  6. 备库磁盘空间: 检查备库的数据目录所在分区是否有足够的空间。磁盘满会导致WAL无法写入,复制中断。

  7. primary_conninfo
    检查: 确认备库的
    postgresql.auto.conf
    postgresql.conf
    中的
    primary_conninfo
    连接字符串是否正确,包括主库IP、端口、用户和密码。

排查问题就像侦探破案,需要耐心和细致。从最基础的网络和权限开始,逐步深入到配置参数和日志分析,通常都能找到症结所在。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

633

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

589

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

172

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

83

2025.08.07

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.6万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号