【PostgreSQL使用】最新功能逻辑复制槽的failover,大数据下高可用再添利器

逻辑复制的failover

专栏内容

个人主页我的主页
管理社区开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

✅ 🔥🔥🔥重大消息🔥🔥🔥 ❤️❤️❤️❤️ 关注公众号【开源无限】有更多数据库优质内容输出 ❤️❤️❤️❤️

一、概述


使用数据库除了存取数据快捷以外,还有一个非常重要的目的,就是它有一整套的机制来保障数据访问的高可用,持续性。

当然逻辑复制也不例外,当我们正在订阅的主库故障发生主备切换时,仍然希望数据库对象的变更订阅不会丢失,能持续收到发布者的消息。

这在以往的PostgreSQL版本中是没有的,最新的PostgreSQL 17版本终于完善了这一功能,逻辑复制支持了failover特性,提升了逻辑复制的高可用性。

本文通过搭建逻辑复制的failover部署,来试一试逻辑复制的failover倒底如何。

在这里插入图片描述

二、 热备集群部署


为了演示带failover的逻辑复制的高可用,首先需要部署一主一备的热备环境,采用流复制的方式对整个主库数据进行实时备份。如果要增加复制槽的备份,当然备库要相较于普通的流复制需要多一些配置,要采用复制槽方式,同时还要打开备份的反馈和复制槽同步开关。

为了有明显区分,在此之外第三个集簇,只对主库的一张表的变动进行订阅,这里采用了逻辑复制的方式,并使用了带有failover的逻辑复制槽。带有failover的逻辑复制槽会在主库创建,因为有自动同步机制,也会在备份被创建。

当主备环境发生切换时,主停机,而备切换为新主;此时订阅者,只需要将连接信息修改为新的主库即可,在此期间发布的变更数据不会丢失,都会被订阅者收到。这就是带failover的逻辑复制槽发挥的作用。

2.1 部署规划

在这里插入图片描述

这里我们部署在同一台机器上,所以区分主要是集簇目录和启动时的端口号。

集簇目录端口号
主库pgA5432 (default)
热备库pgAA15434
订阅库pgB5433

2.2 热备搭建

首先需要部署一套主备集群。

主库采用initdb来初始化创建,而备库采用从主库的备份产生,使用pg_basebackup命令直接进行备份。

  • 初始化主库
[senllang@hatch postgres]$ /opt/postgres/bin/initdb -D pgA
  • 配置主库参数

在启动主库之前,需要提前配置几个参数。

wal_level, 默认为replica, 因为需要使用逻辑复制,修改为 logical;
max_wal_senders, 默认为10,已经足够;
max_replication_slots , 因为用到复制槽,这里默认值为10,已经足够;

  • 启动主库

然后,就可以启动主库。

[senllang@hatch postgres]$ /opt/postgres/bin/pg_ctl -D pgA/  -l logfile start
waiting for server to start.... done
server started
  • 创建备份

使用pg_basebackup命令,这个命令的好处是可以在线建立备份,在这里增加了-C -S slot_pri参数,创建了一个物理复制槽,用于复制槽在主备之间同步,后面的步骤会使用到它,所以在这里提前创建,当然也可以手动创建。

[senllang@hatch postgres]$ /opt/postgres/bin/pg_basebackup -h 127.0.0.1 -U senllang --pgdata=./pgAA1 --progress --verbose -C -S slot_pri
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/2000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created replication slot "slot_pri"
23135/23135 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/2000158
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
  • 配置备库的参数

在备库上要配置主库的连接信息,同时要打开热备的开关,这样就可以在备库进行一些查询操作。

primary_conninfo = 'host=127.0.0.1 port=5432 dbname=postgres'
hot_standby = on 
  • 启动备库

在启动备库之前,先要创建standby信号文件,以standby模式启动备份集簇。

[senllang@hatch postgres]$ touch pgAA1/standby.signal
[senllang@hatch postgres]$  /opt/postgres/bin/pg_ctl -D pgAA1/ -o "-p 5434 " -l logfile start

这里备库启动时, 因为在同台机器上不能与其它产生冲突,指定了它的服务监听端口为5434

  • 验证主备环境

在主库上创建两张表。

[senllang@hatch postgres]$ /opt/postgres/bin/psql -d postgres
psql (17.2)
Type "help" for help.

postgres=# create table production(id int primary key, pname varchar, price int);
CREATE TABLE
postgres=# create table orders(o_id int primary key, p_id int references production(id), amount int);
CREATE TABLE

在备库查询,已经同步过来了。

[senllang@hatch ~]$ /opt/postgres/bin/psql -d postgres -p 5434
psql (17.2)
Type "help" for help.

postgres=# \d
Did not find any relations.
postgres=# \d
           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | orders     | table | senllang
 public | production | table | senllang
(2 rows)

主备模型已经部署完成。

三、带failover的逻辑复制部署


逻辑复制槽要达到failover的效果,要具备两方面的条件:

  • 主备集群已经开启了复制槽的同步功能;
  • 逻辑复制槽被指定了failover参数为true;也就是当复制槽为failover=true时,才可被备库同步;

这两个条件缺一不可,充分且必要,所以准备环节就这两个条件来对环境做分步的部署。

3.1 开启主备复制槽同步

首先要改造主备部署,让它支持复制槽的同步。

这一步必须是在使用带failover的复制槽之前,否则之前的复制槽不能被同步。

这里只需要修改备库参数即可。

配置复制槽的failover相关参数,在备份库pgAA1修改参数:

  • hot_standby_feedback, 修改为 on, 备库可以反馈;
  • sync_replication_slots, 修改为 on, 自动同步复制槽;
  • primary_slot_name, 发送端的主复制槽,设置为备份时创建的复制槽 ‘slot_pri’;当然也可以手动添加;
[senllang@hatch postgres]$  /opt/postgres/bin/pg_ctl -D pgAA1/ -o "-p 5434 " -l logfile reload
server signaled

在修改完备库参数之后,使用reload让参数生效。

3.2 准备订阅库

下面开始逻辑复制的搭建,步聚与之前介绍方法一样。

首先是创建集簇pgB,这与初始化主库的方法一样,使用initdb初始化一个新的集簇,这里不再赘述。

  • 订阅库

订阅库参数配置;

wal_level = logical

启动订阅库,这里指定订阅库监听端口为5433

[senllang@hatch postgres]$  /opt/postgres/bin/pg_ctl -D pgB -o "-p 5433 " -l logfile start
waiting for server to start.... done
server started

3.3 建立逻辑复制

当然就是熟悉的发布与订阅的机制了。

  • 创建发布

在主库创建order表上的条件发布,这里用法更递进一些,只订阅产品号为2的订单信息,因为订阅者就是2号商品的厂家,其它信息与它没有意义。

postgres=# create publication pub_orders for table orders WHERE ( p_id = 2);
CREATE PUBLICATION
  • 创建订阅表

厂家的分析员要收集所有一级代理商的订单信息,这里有一个订单表。

厂家的订单表,可不像代理商需要记录所有商口,所以此处没有外键,因为只有一种商品,甚至可以不用订阅此字段。

postgres=# create table orders(o_id int primary key, p_id int , amount int);
CREATE TABLE
  • 订阅

登陆5433端口的订阅库,创建订阅;这里需要打开订阅时使用的逻辑复制槽的failover开关,默认是关闭的。

postgres=# create subscription orders_2 CONNECTION 'host=127.0.0.1 dbname=postgres port=5432' publication pub_orders with (failover = true);
NOTICE:  created replication slot "orders_2" on publisher
CREATE SUBSCRIPTION

到此,在主备部署下,又带了一个发布订阅的逻辑复制,整体部署就结束了。

3.4 复制槽自动同步

我们在只读的备库上查询一下复制槽的同步情况。

[senllang@hatch ~]$ /opt/postgres/bin/psql -d postgres -p 5434
psql (17.2)
Type "help" for help.

postgres=# select slot_name, failover from pg_replication_slots ;
 slot_name | failover
-----------+----------
 orders_2  | t
(1 row)

可以看到刚才创建的逻辑复制槽已经同步到了备库,同样也可以在主库查询,主库应该有两个复制槽,只有orders_2打开了failover开关,所以才会被同步到了备库。

3.4 条件订阅

当代理商有新的订单产生时,厂家都会收到关于自己家商品的销售情况,进行实时分析,对产品生产计划做出实时调整,这一套流程成熟之后,可以应用AI来完成。不妙啊!又有岗位要被淘汰了。

赶紧看一下逻辑复制是否正常工作,主库模拟产生了两笔订单数据。

postgres=# insert into production values ( 1,'mobile phone'),(2,'labtop');
INSERT 0 2
postgres=# insert into orders values (1,2,200),(2,1,200);
INSERT 0 2
postgres=# select * from orders ;
 o_id | p_id | amount
------+------+--------
    1 |    2 |    200
    2 |    1 |    200
(2 rows)

然后在订阅库上查询,果然厂家立即就可以看到自己家的产品销售额。

postgres=# select * from orders ;
 o_id | p_id | amount
------+------+--------
    1 |    2 |    200
(1 row)

此时,备库上的数据与主库是保持完全一致的。

四、逻辑复制槽failover


到此,逻辑复制槽已经同步到了备库,理应整个演示要结束了。一般都会对于故障比较感兴趣,一定要眼见为实,下面就来看一下逻辑复制的failover。

  • 主库故障

模拟主库发生了故障的情况,这里直接停止主库。

[senllang@hatch postgres]$  /opt/postgres/bin/pg_ctl -D pgA -l logfile stop
waiting for server to shut down.... done
server stopped
  • 备库切换为新的主库

主备会先发生failover,因为是热备,所以直接将备库提升为新的主库,即可保障业务的连续运行。

[senllang@hatch postgres]$  /opt/postgres/bin/pg_ctl -D pgAA1/ -o "-p 5434 " -l logfile promote
waiting for server to promote.... done
server promoted

新主库拥有全量的用户数据,所以并不会发生数据的丢失情况。

  • 逻辑复制failover

当主备发生切换之后,逻辑复制的订阅端也要切换订阅源了,因为逻辑复制信息以及逻辑复槽已经在新主库了,所以现在处理就比较简单了。

订阅库中修改订阅连接信息,更改为新主库的连接信息,端口为5434

postgres=# alter subscription orders_2 connection 'host=127.0.0.1 dbname=postgres port=5434';
ALTER SUBSCRIPTION
  • 验证订阅

为了验证逻辑复制的有效性,继续在新的主库上模拟产生一笔订单数据。

postgres=# insert into orders values(3,2,500);
INSERT 0 1
postgres=# select * from orders ;
 o_id | p_id | amount
------+------+--------
    1 |    2 |    200
    2 |    1 |    200
    3 |    2 |    500
(3 rows)

在订阅库上查看本厂商口的销售情况。

postgres=# select * from orders ;
 o_id | p_id | amount
------+------+--------
    1 |    2 |    200
    3 |    2 |    500
(2 rows)

咦,又多了一笔销售数据,金额还不小。

五、总结


逻辑复制槽的failover功能是PostgreSQL 17版本新增的功能,这也完善了逻辑复制的故障场景的处理策略,避免此场景下的变更数据丢失情况。

各位小伙伴get到了吗,也记得点个赞再走哟~

结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

评论 315
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩楚风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值