PostgreSQL 流复制配置环境搭建过程

 更新时间:2023年09月07日 11:48:32   作者:Bing@DBA  
PostgreSQL 流复制是 9.0 提供的一种新的 WAL 传递方法,使用流复制时,每当 Primary 节点 WAL 产生,就会马上传递到 Standby 节点,流复制提供异步和同步两种模式,同步模式可以保障数据 0 丢失,这篇文章主要介绍了PostgreSQL 流复制搭建,需要的朋友可以参考下

前言

PostgreSQL 流复制(Streaming Replication)是 9.0 提供的一种新的 WAL 传递方法。使用流复制时,每当 Primary 节点 WAL 产生,就会马上传递到 Standby 节点,流复制提供 异步 同步 两种模式,同步模式可以保障数据 0 丢失。

1. 配置环境

1.1 环境介绍

主机名IP 地址角色数据目录
172-16-104-7172.16.104.7Master/data/pgsql12/data/
172-16-104-56172.16.104.56Standby/data/pgsql12/data/

PostgreSQL 版本:PostgreSQL 12.2操作系统:CentOS Linux release 7.8.2003 (Core)

1.2 主库白名单

Master 节点配置 pg_hba.conf 表示接受流复制的用户连接:

host    replication     all             0/0                     md5

上面这条 SQL 语句的含义是允许任意用户从任何网络(0/0)网络上发起到本数据库的流复制连接,使用MD5的密码认证。

1.3 主库参数配置

# 监听
listen_addresses = '*'
# 流复制客户端的最大并发数,设置为 0 表示禁用复制
max_wal_senders = 10
# WAL 日志级别
wal_level = replica

上面的参数需要重启 PostgreSQL 服务后生效。

2. 流复制搭建

使用 pg_basebackup 将主库数据备份恢复到 Standby 节点,搭建 异步/同步 流复制,步骤归纳:

  • 准备环境 PostgreSQL 主节点和备节点。
  • 参数调整 pg_hba.conf、postgresql.conf,创建复制用户。
  • 备份主节点的数据,恢复到备节点。
  • 修改 primary_conninfo 启动备库。
  • 检查是否启动成功。

2.1 备份恢复

在主库执行全量备份:

pg_basebackup -D /data/pgsql12/backup  -v -P -X stream -Upostgres -h 127.0.0.1 -p5432 -R

将备份 SCP 到备库节点:

scp -r ./backup/ root@172.16.104.56:/data/backup

关闭 Standby 节点,清空 Standby 节点的数据文件,或者使用 mv 修改目录名:

# 备份数据目录,或者可以直接清空
mv /data/pgsql12/data /data/pgsql12/data_bak
# 将备份文件转移到数据目录
mv /data/pgsql12/backup /data/pgsql12/data
# 修改文件属组
chown -R postgres:postgres /data/pgsql12

2.2 创建复制用户

主库创建专用于流复制的用户:

CREATE ROLE repl REPLICATION LOGIN PASSWORD 'repl123';

2.3 参数修改

PostgreSQL 使用 standby.signal 文件表示实例为 Standby 节点。在使用 pg_basebackup 备份添加 -R 参数(write configuration for replication)会在 postgresql.auto.conf 文件中写入 primary_conninfo 参数信息,这里我们需要按照实际情况调整:

primary_conninfo = 'host=172.16.104.7 port=5432 user=repl password=repl123'

2.4 启动并检查

参数配置完成后,启动 Standby 节点即可:

pg_ctl -D /data/pgsql12/data/ -l /data/pgsql12/logs/start.log start

在主节点,可通过下方 SQL 查询流复制的监控信息:

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 27408
usesysid         | 24865
usename          | repl
application_name | walreceiver
client_addr      | 172.16.104.56
client_hostname  | 
client_port      | 40990
backend_start    | 2023-09-05 14:11:56.978627+08
backend_xmin     | 
state            | streaming
sent_lsn         | 6/4001BB0
write_lsn        | 6/4001BB0
flush_lsn        | 6/4001BB0
replay_lsn       | 6/4001BB0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async
reply_time       | 2023-09-05 15:03:58.408518+08

其中 state = streaming 表示流复制状态正常,如果有异常,可以查看 error log 中的信息,或者启动的时候就 tail -f error_log,实时关注输出的异常信息。

2.5 同步流复制

上面 2.1~2.4 是介绍如何搭建 异步 流复制。

PostgreSQL 异步流复制的缺点是当主库损坏的时候,激活备库可能会丢失一部分数据,这于 MySQL 异步复制相同,主库只管发送增量日志,挂掉后可能有部分日志从库还没有接收到,此时发生切换就会出现数据丢失,同步复制可以解决该类问题。不过需要注意的是,如果配置同步复制 Standby 节点挂掉,会导致 Priamry 节点卡住,所以一般会有多个 Standby 节点,至少保障 WAL 同步到一个 Standby 节点。

同步复制配置多加一个 synchronous_standby_names 参数,有 3 种配置方法:

synchronous_standby_names = 's1,s2,s3'

在这个例子中,如果有 s1、s2、s3 三台 Standby 节点在运行,意味着 s1 为同步节点,其他节点均为潜在同步节点,即 WAL 只需传递给 s1 节点就可以提交。

synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'

在这个例子中,如果有四个后备服务器 s1、s2、s3 和 s4 在运行,两个后备服务器 s1 和 s2 将被选中为同步后备,因为它们出现在后备服务器名称列表的前部。s3 是一个潜在的同步后备,当 s1 或 s2 中的任何一个失效, 它就会取而代之。s4 则是一个异步后备因为它的名字不在列表中。

synchronous_standby_names = 'ANY 2 (s1, s2, s3)'

在这个例子中,如果有四台后备服务器 s1、s2、s3 以及 s4 正在运行,事务提交将会等待来自至少其中任意两台后备服务器的回复。s4 是一台异步后备,因为它的名字不在该列表中。

现在我们的架构是一个 Primary 节点一个 Standby 节点,现在通过修改参数调整为 同步流复制 修改主库参数:

# 其中 walreceiver 为 Standby 节点的名字,由 primary_conninfo 中的 application_name 设置
synchronous_standby_names = 'walreceiver'

修改该参数不需要重启数据库,使用 reload 重新加载配置即可:

pg_ctl reload -D /data/pgsql12/data/

在 Primary 节点查询流复制的状态信息:

postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 13561
usesysid         | 24865
usename          | repl
application_name | walreceiver
client_addr      | 172.16.104.56
client_hostname  | 
client_port      | 42126
backend_start    | 2023-09-06 17:18:48.297466+08
backend_xmin     | 
state            | streaming
sent_lsn         | 6/50007D0
write_lsn        | 6/50007D0
flush_lsn        | 6/50007D0
replay_lsn       | 6/50007D0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | sync
reply_time       | 2023-09-06 17:45:00.706196+08

其中 sync_stateasync 变为 sync 表示为同步模式。

2.6 同步复制级别

影响同步复制还需要关注一个参数 synchronous_commit 用来设置事务的同步级别:

postgres=# select * from pg_settings where name = 'synchronous_commit';
-[ RECORD 1 ]---+------------------------------------------------------
name            | synchronous_commit
setting         | on
unit            | 
category        | Write-Ahead Log / Settings
short_desc      | Sets the current transaction's synchronization level.
extra_desc      | 
context         | user
vartype         | enum
source          | default
min_val         | 
max_val         | 
enumvals        | {local,remote_write,remote_apply,on,off}
boot_val        | on
reset_val       | on
sourcefile      | 
sourceline      | 
pending_restart | f
  • local:WAL 日志被本地持久化后(不用管远程)事务 commit 就可以返回。
  • remote_write:WAL 日志被传到备库的内存中(不必等其被持久化)事务 commit 才返回。
  • remote_apply:WAL 日志被传到备库并被 apply,事务 commit 才返回。
  • on:WAL 日志被传到备库并被持久化(不必等其被 apply)事务 commit 才返回。
  • off:不必等 WAL 日志被本地持久化,也不管是否传到远程,事务 commit 都可以立即返回。

对于同步复制,可选的值有 remote_write、remote_apply、on。

3. 流复制监控

3.1 角色判断

select pg_is_in_recovery();

判断数据库是否为主库 f 表示是主库, t 表示属于备库角色。

3.2 主库查看流复制

查看流复制信息,可以在主库查看 pg_stat_replication 视图,可以查看流复制的状态信息:

  • sent_lsn:发送 WAL 的位置。
  • write_lsn:备库已接收到这部分日志,但还没有刷到磁盘中。
  • flush_lsn:备库已把 WAL 写入到磁盘中。
  • replay_lsn:备库应用 WAL 的位置。
  • sync_state:同步模式。
  • state:流复制状态。
select * from pg_stat_replication;

输出结果:

postgres=# \x
Expanded display is on.

postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 13561
usesysid         | 24865
usename          | repl
application_name | walreceiver
client_addr      | 172.16.104.56
client_hostname  | 
client_port      | 42126
backend_start    | 2023-09-06 17:18:48.297466+08
backend_xmin     | 
state            | streaming
sent_lsn         | 6/50007D0
write_lsn        | 6/50007D0
flush_lsn        | 6/50007D0
replay_lsn       | 6/50007D0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | sync
reply_time       | 2023-09-07 10:06:18.000504+08

3.3 延迟监控

使用下方 SQL 可以查看 Standby 节点落后主库多少字节 WAL 日志:

select pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) from pg_stat_replication; 

3.4 备库查询复制信息

在备库也可以通过查询 pg_stat_wal_receiver 视图,获得流复制的监控信息:

  • pid:WAL 接收进程 ID。
  • status:流复制状态,只有 streaming 为正常状态。
  • receive_start_lsn:WAL 接收进程启动时使用的第一个 WAL 日志的位置。
  • receive_start_tli:WAL 接收进程启动时使用的第一个时间线编号。
  • received_lsn:已经接收到并且已经被写入磁盘的最后一个 WAL 日志的位置。
  • received_tli:已经接收到并且已经被写入磁盘的最后一个 WAL 日志的时间线编号。
  • last_msg_send_time:接收到最后一条 WAL 日志消息后,向主库发回确认消息的发送时间。
  • last_msg_receipt_time:备库接收到最后一条 WAL 日志消息的接收时间。
  • slot_name:使用复制槽的名称。
  • conninfo:连接主库的连接串,密码等安全相关的信息会被隐去。
select * from pg_stat_wal_receiver;
postgres=# \x
Expanded display is on.
postgres=# 
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 113395
status                | streaming
receive_start_lsn     | 6/5000000
receive_start_tli     | 3
received_lsn          | 6/50007D0
received_tli          | 3
last_msg_send_time    | 2023-09-07 10:20:00.207856+08
last_msg_receipt_time | 2023-09-07 10:20:00.20971+08
latest_end_lsn        | 6/50007D0
latest_end_time       | 2023-09-06 17:19:46.661221+08
slot_name             | 
sender_host           | 172.16.104.7
sender_port           | 5432
conninfo              | user=repl password=******** dbname=replication host=172.16.104.7 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any

到此这篇关于PostgreSQL 流复制搭建的文章就介绍到这了,更多相关PostgreSQL 流复制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • postgres之jsonb属性的使用操作

    postgres之jsonb属性的使用操作

    这篇文章主要介绍了postgres之jsonb属性的使用操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • PostgreSQL 序列增删改案例

    PostgreSQL 序列增删改案例

    这篇文章主要介绍了PostgreSQL 序列增删改案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Windows 环境搭建 PostgreSQL 逻辑复制高可用架构数据库服务

    Windows 环境搭建 PostgreSQL 逻辑复制高可用架构数据库服务

    本文主要介绍Windows下搭建PostgreSQL的主从逻辑复制,关于PostgreSQl的相关运维文章,网络上大多都是 Linux 环境下的操作,鲜有在 Windows 环境下配置的教程,所以本文采用 Windows 环境作为演示系统来进行 PostgreSQL 高可用数据库服务的搭建,感兴趣的朋友一起看看吧
    2023-05-05
  • PostgreSQL运维案例之递归查询死循环解决方案

    PostgreSQL运维案例之递归查询死循环解决方案

    PostgreSQL提供的递归语法是很棒的,例如可用来解决树形查询的问题,解决Oracle用户connect by的语法兼容性,下面这篇文章主要给大家介绍了关于PostgreSQL运维案例之递归查询死循环解决方案的相关资料,需要的朋友可以参考下
    2024-02-02
  • 使用postgresql 模拟批量数据插入的案例

    使用postgresql 模拟批量数据插入的案例

    这篇文章主要介绍了使用postgresql 模拟批量数据插入的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL数据库中匿名块的写法实例

    PostgreSQL数据库中匿名块的写法实例

    这篇文章主要介绍了PostgreSQL数据库中匿名块的写法实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL 如何修改文本类型字段的存储方式

    PostgreSQL 如何修改文本类型字段的存储方式

    这篇文章主要介绍了PostgreSQL 如何修改文本类型字段的存储方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 在Ubuntu中安装Postgresql数据库的步骤详解

    在Ubuntu中安装Postgresql数据库的步骤详解

    PostgreSQL 是一款强大的,开源的,对象关系型数据库系统。它支持所有的主流操作系统,包括 Linux、Unix(AIX、BSD、HP-UX,SGI IRIX、Mac OS、Solaris、Tru64) 以及 Windows 操作系统。本文给大家介绍了在Ubuntu中安装Postgresql数据库的步骤,需要的朋友可以参考下。
    2017-09-09
  • 解决postgresql 自增id作为key重复的问题

    解决postgresql 自增id作为key重复的问题

    这篇文章主要介绍了解决postgresql 自增id作为key重复的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 浅谈pg_hint_plan定制执行计划

    浅谈pg_hint_plan定制执行计划

    这篇文章主要介绍了浅谈pg_hint_plan定制执行计划操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01

最新评论