postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

前言

  最近工作中做了些postgre的数据同步的工作,详细记录下实现过程。

文档示例

数据库表的逻辑复制示例    

前提

0、下面案例中使用pgcli终端工具操作。

1、要使用逻辑复制,需要先为集群参数组设置 rds.logical_replication 参数为1(如果之前没有设置,从0修改为1后需要重启RDS!)。然后设置发布者和订阅者。

2、要为 PostgreSQL 数据库执行逻辑复制,您的 AWS 用户账户需要有 rds_superuser 角色。

3、您用作源的 RDS for PostgreSQL 数据库实例必须启用自动备份。有关如何为 RDS for PostgreSQL 数据库实例启用自动备份的说明,请参阅 Amazon RDS 用户指南 中的启动自动备份

详细的操作过程 -- 使用一个demo实现

提示

0、建议使用docker在本地启动2个RDS,一个当作发布者,另外一个当作订阅者

1、使用runfast-02这个RDS为发布者,runfast-02-new这个RDS作为订阅者

2、分别在两个RDS中新建数据库做测试!

??3、此操作需要superuser权限的账号!

在发布者DB中创建发布

CREATE PUBLICATION

-- 使用runfast02的超级用户进入
pgcli -D 010_runfast02_super

-- test 创建一个新数据库
create database test_publication_db;

-- 在里面创建一张新表
use test_publication_db;

CREATE TABLE users(
    id INT PRIMARY KEY     NOT NULL,
    name           varchar(10)    NOT NULL,
    age            INT     NOT NULL
 );


-- 插入几条数据(插入数据跟创建publication的操作顺序没有先后)
insert into users(id, name, age) values(123,whw222,22),(2222,www222,23);

insert into users(id, name, age) values(8,whw8,88);


-- 创建publication
create publication test_pub for all tables;
-- CREATE PUBLICATION
-- 为单独一张表创建发布者: create publication test_pub for table users;

-- 查看发布者
table pg_publication;
-- 或者
select * from pg_catalog.pg_publication;

-- 删除发布
DROP PUBLICATION [ IF EXISTS ] name [, ...];

发布者创建成功后可以从pg_publication这张表中查看一下结果:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

??管理发布

CREATE PUBLICATION name
    [ FOR TABLE [ ONLY ] table_name [ * ] [, ...]
      | FOR ALL TABLES ]
    [ WITH ( publication_parameter [= value] [, ... ] ) ]

ALTER PUBLICATION name ADD TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name SET TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name DROP TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] )
ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
ALTER PUBLICATION name RENAME TO new_name

DROP PUBLICATION [ IF EXISTS ] name [, ...];

在订阅者DB中创建订阅

CREATE SUBSCRIPTION

-- 使用runfast02_ne的超级用户进入
pgcli -D 010_runfast02_new_super

create database test_subscription_db;

use test_subscription_db;


CREATE TABLE users(
    id INT PRIMARY KEY     NOT NULL,
    name           varchar(10)    NOT NULL,
    age            INT     NOT NULL
);


-- 注意 PUBLICATION的名字要写上面创建的发布者的名字!!!
-- ??注意 链接信息要写“发布者”的(本例中是 runfast-02的!)
CREATE SUBSCRIPTION test_sub CONNECTION host=xxx-xxx-runfast02.xxx.rds.cn-xxx-1.xxx.com.cn port=4432 dbname=test_publication_db user=postgres password=xxx&xxx PUBLICATION test_pub; 


-- 查看订阅
table pg_subscription
-- 或者
select * from pg_catalog.pg_subscription;


-- 在订阅者上查看“复制槽”
table pg_replication_slots


-- 删除订阅
DROP SUBSCRIPTION [ IF EXISTS ] name;

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

 ??管理订阅

CREATE SUBSCRIPTION subscription_name
    CONNECTION conninfo
    PUBLICATION publication_name [, ...]
    [ WITH ( subscription_parameter [= value] [, ... ] ) ]

ALTER SUBSCRIPTION name CONNECTION conninfo
ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( set_publication_option [= value] [, ... ] ) ]
ALTER SUBSCRIPTION name REFRESH PUBLICATION [ WITH ( refresh_option [= value] [, ... ] ) ]
ALTER SUBSCRIPTION name ENABLE
ALTER SUBSCRIPTION name DISABLE
ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] )
ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
ALTER SUBSCRIPTION name RENAME TO new_name

DROP SUBSCRIPTION [ IF EXISTS ] name;

管理复制槽

?? 订阅者创建成功后会自动在发布者那边创建一个对应的复制槽

?订阅者创建成功后会自动在发布者那边创建一个对应的复制槽

??复制槽相关的资料

PostgreSQL复制槽实操

管理复制槽:

每个活跃的订阅都会通过复制槽 从远程发布者接受变更。

??通常这个远端的复制槽是自动管理的,在CREATE SUBSCRIPTION时自动创建,在DROP SUBSCRIPTION时自动删除。

在特定场景下,可能需要分别操作订阅与底层的复制槽:

  • 创建订阅时,所需的复制槽已经存在。则可以通过create_slot = false关联已有复制槽。

  • 创建订阅时,远端不可达或状态不明朗,则可以通过connect = false不访问远程主机,pg_dump就是这么做的。这种情况下,您必须在远端手工创建复制槽后,才能在本地启用该订阅。

  • ??移除订阅时,需要保留复制槽。这种情况通常是订阅者要搬到另一台机器上去,希望在那里重新开始订阅。这种情况下需要先通过ALTER SUBSCRIPTION解除订阅与复制槽点关联

  • ??移除订阅时,远端不可达。这种情况下,需要在删除订阅之前使用ALTER SUBSCRIPTION解除复制槽与订阅的关联。

    如果远端实例不再使用那么没事,然而如果远端实例只是暂时不可达,那就应该手动删除其上的复制槽;否则它将继续保留WAL,并可能导致磁盘撑爆。

??case1-发布者RDS断链后,drop订阅者遇到的问题

1、在订阅者中移除订阅,如果遇到远端不可达的情况(远端发布者的RDS中的那个数据库被删掉了等情况),直接删除subscription的话会报错:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

2、根据提示需要更新一下这个订阅者,先将这个订阅者disable一下,然后将它的slot_name改成NONE后再删除:

2-1、注意需要线disable一下这个订阅者:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

 2-2、然后再将它的slot_name改成NONE最后删除即可:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

?? case2-订阅者RDS断链后,在发布者中删除无用的复制槽的操作

??1、一般情况下,如果订阅者的subscription被删除的话,发布者中对应的复制槽也会被删除,但是实际在测试的时候遇到了下面这种情况:测试完后将runfast0-new这台RDS从AWS中移除了!但是在此之前并没有删掉RDS中test_subscription_db这张表中的订阅者subscription,导致了发布者中遗留下了一个没有用的复制槽,如果确认复制槽没有用的话可以直接进行删除:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

 ??2、实际上,如果复制槽还在用的话,直接删除会报错的:

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

逻辑复制成功后的同步延迟相关资料

【1】https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Replication.Logical.html

【2】https://www.postgresql.org/docs/11/monitoring-stats.html#PG-STAT-REPLICATION-VIEW

【3】https://www.postgresql.org/docs/11/monitoring-stats.html#PG-STAT-SUBSCRIPTION-VIEW

 

 

postgreSQL进行RDS间的逻辑复制与DB同步的详细实现

上一篇:分布式架构1:mysql集群(Mysql Cluster7.5.5)


下一篇:10条SQL优化技巧