PG主从系列-逻辑复制

前言

  Postgresql支持“逻辑”和“物理”两种复制方式,逻辑复制是一种基于数据对象的复制标识(通常是主键)复制数据对象及其修改的方法,而后者使用准确的块地址以及逐字节的复制方式(WAL日志),逻辑复制允许数据复制和安全性上更细粒度的控制(可以对特定表进行复制)。逻辑复制采用发布者->订阅者模型,具体流程结构图如下:

逻辑复制的能力:

  1、一个数据库或者一个数据库子集发生更改时,把增量的改变发送给订阅者。

  2、在更改到达订阅者时引发触发器。

  3、把多个数据库联合到单一数据库。

  4、在Postgresql不同主版本之间进行复制。

  5、在不同的平台(例如Linux到Windows)的Postgresql实例之间复制。

  6、将复制数据的访问给予不同的用户组。

  7、在多个数据库之间共享数据库的子集。

  8、Pubilcation可以选择把它们产生的更改限制为INSERT、UPDATE、DELETE及UPDATE的任意组合。

  9、表的列通过名称匹配。订阅表中的列顺序不需要与发布表顺序一致;列的数据类型也不需要一样,只要可以将数据的文本表示转换为目标类型即可,如:int列复制到bigint列,此外目标表还可以具备发布表中不存在的额外列,额外列将以定义的默认值填充。

逻辑复制限制:

  1、一个订阅被删除并且重建时,同步信息会丢失,数据必须重新同步。

  2、表在发布者和订阅者之间使用完全限定的表名进行匹配,不支持复制到订阅者上命名不同的表,同时列名也必须匹配不能映射。

  3、采用复制槽的方式,当存在冲突时,复制会暂停,需要人工处理,可能导致发布节点WAL日志积压严重,严重情况下导致发布节点不可用。

  4、数据库模式和DDL命令不会被复制

  5、序列数据不被复制

  6、大对象不会被复制

  7、复制只能是普通表,不能是视图、物化视图、分区根表或者外部表;如果是分区,可以一一对应地复制分区层次,但当前不能复制成一种不同的分区设置。

  8、支持TRUNCATE但是当使用cascade清空,而表存在外键类链接时,如果受影响的表属于同一订阅,这会正确工作,但是不属于同一订阅的表时,会报错。

  9、要求PG9.4及以上版本

  10、复制表需要有主键、或者唯一性约束,否则只能设置replica identity补全日志

  11、复制用户权限需要replication或superuser权限

快速部署

1、修改发布者postgres.conf文件

wal_level = logical
max_wal_senders = 100

2、发布者节点创建用户

#以public模式为例
create
user repl replication with password 'repl'; alter user repl set default_transaction_read_only=on; grant USAGE on SCHEMA public to repl; grant SELECT on ALL tables in schema public to repl; alter default privileges in schema public grant select on tables to repl;

3、修改发布者节点pg_hba.conf文件

host    all    repl    订阅者IP/32    md5

4、重启PG

su - postgres -c "pg_ctl restart"

5、发布者节点创建发布

create publication pub1 for table tab1;
--alter table tab1 replica identity full; --无主键或者唯一性约束时开启补全日志,此时会导致复制效率很低

6、订阅者节点

#max_replication_slots需要设置
#max_logical_replication_workers需要设置
#max_worker_processes需要设置
#创建表结构
create
subscription pub1 connection 'host=发布者IP post=5432 dbname=postgres user=repl password=repl' publication pub1; alter subscription pub1 refresh publication;

运维监控

alter publication pub1 add table test.tab1;#从节点需要刷新才能看到新添加表
alter subscription pub1 refresh publication; #刷新订阅
drop pubilcation pub1; #删除发布
select * from pg_pubilcation;#发布
select * from pg_pubilcation_tables;#发布哪些表
select * from pg_stat_subscription;#复制进度
select * from pg_subscription; #订阅
select *,srrelid::regclass from pg_subscription_rel; #订阅哪些表
drop subscription pub1;#删除订阅

冲突处理

update或delete操作时可能会导致冲突,这时可以查看日志刚刚订阅者上的数据,或者使用pg_replication_origin_advance()函数跳过该事务。

 

posted @ 2020-12-19 15:53  DUAN的博客  阅读(2497)  评论(0编辑  收藏  举报