Postgres逻辑复制详解

news/2024/11/23 9:57:23/

逻辑复制

逻辑复制(Logical Replication),是一种根据数据对象的 复制标识(Replica Identity)(通常是主键)复制数据对象及其变化的方法。

逻辑复制 这个术语与 物理复制相对应,物理复制使用精确的块地址与逐字节复制,而逻辑复制则允许对复制过程进行精细的控制。

逻辑复制基于 发布(Publication) 与 订阅Subscription)模型:

  • 一个 发布者(Publisher) 上可以有多个发布,一个 订阅者(Subscriber) 上可以有多个 订阅 。
  • 一个发布可被多个订阅者订阅,一个订阅只能订阅一个发布者,但可订阅同发布者上的多个不同发布。

针对一张表的逻辑复制通常是这样的:订阅者获取发布者数据库上的一个快照,并拷贝表中的存量数据。一旦完成数据拷贝,发布者上的变更(增删改清)就会实时发送到订阅者上。订阅者会按照相同的顺序应用这些变更,因此可以保证逻辑复制的事务一致性。这种方式有时候又称为 事务性复制(transactional replication)

逻辑复制的典型用途是:

  • 迁移,跨PostgreSQL大版本,跨操作系统平台进行复制。
  • CDC,收集数据库(或数据库的一个子集)中的增量变更,在订阅者上为增量变更触发触发器执行定制逻辑。
  • 分拆,将多个数据库集成为一个,或者将一个数据库拆分为多个,进行精细的分拆集成与访问控制。

逻辑订阅者的行为就是一个普通的PostgreSQL实例(主库),逻辑订阅者也可以创建自己的发布,拥有自己的订阅者。

如果逻辑订阅者只读,那么不会有冲突。如果会写入逻辑订阅者的订阅集,那么就可能会出现冲突。

发布(Publication)

一个 发布(Publication) 可以在物理复制主库 上定义。创建发布的节点被称为 发布者(Publisher) 。

一个 发布 是 由一组表构成的变更集合。也可以被视作一个 变更集(change set) 或 复制集(Replication Set) 。每个发布都只能在一个 数据库(Database) 中存在。

发布不同于模式(Schema),不会影响表的访问方式。(表纳不纳入发布,自身访问不受影响)

发布目前只能包含(即:索引,序列号,物化视图这些不会被发布),每个表可以添加到多个发布中。

除非针对ALL TABLES创建发布,否则发布中的对象(表)只能(通过ALTER PUBLICATION ADD TABLE)被显式添加

发布可以筛选所需的变更类型:包括INSERTUPDATEDELETE 和TRUNCATE的任意组合,类似触发器事件,默认所有变更都会被发布。

复制标识

一个被纳入发布中的表,必须带有 复制标识(Replica Identity),只有这样才可以在订阅者一侧定位到需要更新的行,完成UPDATEDELETE操作的复制。

默认情况下,主键 (Primary Key)是表的复制标识,非空列上的唯一索引 (UNIQUE NOT NULL)也可以用作复制标识。

如果没有任何复制标识,可以将复制标识设置为FULL,也就是把整个行当作复制标识。(一种有趣的情况,表中存在多条完全相同的记录,也可以被正确处理,见后续案例)使用FULL模式的复制标识效率很低(因为每一行修改都需要在订阅者上执行全表扫描,很容易把订阅者拖垮),所以这种配置只能是保底方案。使用FULL模式的复制标识还有一个限制,订阅端的表上的复制身份所包含的列,要么与发布者一致,要么比发布者更少。

INSERT操作总是可以无视 复制标识 直接进行(因为插入一条新记录,在订阅者上并不需要定位任何现有记录;而删除和更新则需要通过复制标识 定位到需要操作的记录)。如果一个没有 复制标识 的表被加入到带有UPDATEDELETE的发布中,后续的UPDATEDELETE会导致发布者上报错。

表的复制标识模式可以查阅pg_class.relreplident获取,可以通过ALTER TABLE进行修改。

ALTER TABLE tbl REPLICA IDENTITY 
{ DEFAULT | USING INDEX index_name | FULL | NOTHING };

尽管各种排列组合都是可能的,然而在实际使用中,只有三种可行的情况。

  • 表上有主键,使用默认的 default 复制标识
  • 表上没有主键,但是有非空唯一索引,显式配置 index 复制标识
  • 表上既没有主键,也没有非空唯一索引,显式配置full复制标识(运行效率非常低,仅能作为兜底方案)
  • 其他所有情况,都无法正常完成逻辑复制功能。输出的信息不足,可能会报错,也可能不会。
  • 特别需要注意:如果nothing复制标识的表纳入到逻辑复制中,对其进行删改会导致发布端报错!

管理发布

CREATE PUBLICATION用于创建发布,DROP PUBLICATION用于移除发布,ALTER PUBLICATION用于修改发布。

发布创建之后,可以通过ALTER PUBLICATION动态地向发布中添加或移除表,这些操作都是事务性的。

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_nameDROP PUBLICATION [ IF EXISTS ] name [, ...];

publication_parameter 主要包括两个选项:

  • publish:定义要发布的变更操作类型,逗号分隔的字符串,默认为insert, update, delete, truncate
  • publish_via_partition_root:13后的新选项,如果为真,分区表将使用根分区的复制标识进行逻辑复制。

订阅

订阅(Subscription) 是逻辑复制的下游。定义订阅的节点被称为 订阅者(Subscriber) 。

订阅定义了:如何连接到另一个数据库,以及需要订阅目标发布者上的哪些发布

逻辑订阅者的行为与一个普通的PostgreSQL实例(主库)无异,逻辑订阅者也可以创建自己的发布,拥有自己的订阅者。

每个订阅者,都会通过一个 复制槽(Replication) 来接收变更,在初始数据复制阶段,可能会需要更多的临时复制槽。

逻辑复制订阅可以作为同步复制的备库,备库的名字默认就是订阅的名字,也可以通过在连接信息中设置application_name来使用别的名字。

只有超级用户才可以用pg_dump转储订阅的定义,因为只有超级用户才可以访问pg_subscription视图,普通用户尝试转储时会跳过并打印警告信息。

逻辑复制不会复制DDL变更,因此发布集中的表必须已经存在于订阅端上。只有普通表上的变更会被复制,视图、物化视图、序列号,索引这些都不会被复制。

发布与订阅端的表是通过完整限定名(如public.table)进行匹配的,不支持把变更复制到一个名称不同的表上。

发布与订阅端的表的列也是通过名称匹配的。列的顺序无关紧要,数据类型也不一定非得一致,只要两个列的文本表示兼容即可,即数据的文本表示可以转换为目标列的类型。订阅端的表可以包含有发布端没有的列,这些新列都会使用默认值填充。

管理订阅

CREATE SUBSCRIPTION用于创建订阅,DROP SUBSCRIPTION用于移除订阅,ALTER SUBSCRIPTION用于修改订阅。

订阅创建之后,可以通过ALTER SUBSCRIPTION 随时暂停恢复订阅。

移除并重建订阅会导致同步信息丢失,这意味着相关数据需要重新进行同步。

CREATE SUBSCRIPTION subscription_nameCONNECTION '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_nameDROP SUBSCRIPTION [ IF EXISTS ] name;

 

subscription_parameter定义了订阅的一些选项,包括:

  • copy_data(bool):复制开始后,是否拷贝数据,默认为真
  • create_slot(bool):是否在发布者上创建复制槽,默认为真
  • enabled(bool):是否启用该订阅,默认为真
  • connect(bool):是否尝试连接到发布者,默认为真,置为假会把上面几个选项强制设置为假。
  • synchronous_commit(bool):是否启用同步提交,向主库上报自己的进度信息。
  • slot_name:订阅所关联的复制槽名称,设置为空会取消订阅与复制槽的关联。

http://www.ppmy.cn/news/52378.html

相关文章

15、Context

目录 一、常规gorutine控制二、context控制groutine1 - 使用context控制单个gorutine2 - context创建3 - context函数4 - Context接口5 - 使用context控制多个gorutine停止 一、常规gorutine控制 控制并发的两种方式: 使用WaitGroup:多个Goroutine执行同…

C++ auto用法

文章目录 1.auto作用2. auto的原理3.使用auto的细则 1.auto作用 auto关键字能够自动识别变量类型。 2. auto的原理 auto定义的变量会在编译阶段根据右值来推出auto变量的类型。 1.使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来…

SIP协议之通话转接

一、介绍 在SIP协议应用中,有一个常用的功能叫通话转接,用于将接通后的通话转给第三方接听处理。 二、原理及流程 转接是通过SIP协议的一个扩展请求方法REFER实现的。呼叫转接由RFC5589(Session Initiation Protocol (SIP) Call Control - Transfer)定义…

使用D435i深度相机运行ORB-SLAM3

下载安装链接 下载ORB-SLAM3地址: git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git eigen3多版本安装:https://blog.csdn.net/weixin_41756645/article/details/129570141 ORB-SLAM2中eigen3版本为:3.2.10版本 ORB-SLAM3中eigen3版…

【小技巧】word文档编辑技巧(一)

文章目录 一、显示显示导航显示所有字符 二、格式格式-三级目录格式-文本格式-图格式-表格式-公式格式-参考文献 三、小技巧交叉引用连续交叉引用表/图目录等自动更新分节符设置页眉/页码word转pdf带导航 一、显示 显示导航 开启导航:视图->显示框->导航窗格…

初窥Edubuntu 23.04:装有教育软件的Ubuntu桌面

导读4月20日,Edubuntu将作为Ubuntu官方口味卷土重来,作为即将发布的Ubuntu 23.04(Lunar Lobster)的一部分,所以我认为让你们先看看这个重制版中包含的内容是个好主意。 Edubuntu以前被称为Ubuntu教育版,最…

训练数据集处理

列子数据: -- https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip 由于 TSV 只是 CSV 的一种变体,它使用制表符而不是逗号作为分隔符,我们可以通过使用csv加载脚本并delimiter在load_dataset()函数中指定参…

DJ4-1 存储器的层次结构

目录 4.1.1 存储器的层次结构 1. 主存储器(内存,主存,可执行存储器) 2. 寄存器 3. 高速缓存 4. 磁盘缓存 存储器层次结构的特点 4.1.2 存储器管理的目的和功能 1. 主存储器的分配和管理 2. 提高主存储器的利用率 3. 扩…