PostgreSQL教程(三十四):服务器管理(十六)之逻辑复制

逻辑复制是一种基于数据对象的复制标识(通常是主键)复制数据对象及其更改的方法。我们使用术语“逻辑”来与物理复制加以区分,后者使用准确的块地址以及逐字节的复制方式。PostgreSQL两种机制都支持。逻辑复制允许在数据复制和安全性上更细粒度的控制。

逻辑复制使用一种发布订阅模型,其中有一个或者更多订阅者订阅一个发布者节点上的一个或者更多发布 。订阅者从它们所订阅的发布拉取数据并且可能后续重新发布这些数据以允许级联复制或者更复杂的配置。

一个表的逻辑复制通常开始于对发布者服务器上的数据取得一个快照并且将快照拷贝给订阅者。一旦这项工作完成,发布者上的更改会被实时发送给订阅者。订阅者以与发布者相同的顺序应用那些数据,这样在一个订阅中能够保证发布的事务一致性。这种数据复制的方法有时候也被称为事务性复制。

逻辑复制的典型用法是:

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

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

  • 把多个数据库联合到单一数据库中(例如用于分析目的)。

  • 在PostgreSQL的不同主版本之间进行复制。

  • 在不同平台上(例如Linux到Windows)的PostgreSQL实例之间进行复制。

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

  • 在多个数据库间共享数据库的一个子集。

订阅者数据库的行为与任何其他PostgreSQL实例相同,并且可以被用作其他数据库的发布者,只需要定义它自己的发布。当订阅者被应用当作只读时,单一的订阅中不会有冲突。在另一方面,如果应用或者对相同表集合的订阅者执行了其他的写动作,冲突可能会发生。

一、发布

发布可以被定义在任何物理复制的主服务器上。定义有发布的节点被称为发布者。发布是从一个表或者一组表生成的改变的集合,也可以被描述为更改集合或者复制集合。每个发布都只存在于一个数据库中。

发布与模式不同,不会影响表的访问方式。如果需要,每个表都可以被加入到多个发布。当前,发布只能包含表。对象必须被明确地加入到发布,除非发布是用ALL TABLES创建的。

Publication可以选择把它们产生的更改限制为INSERTUPDATEDELETE以及TRUNCATE的任意组合,类似于触发器如何被特定事件类型触发的方式。默认情况下,所有操作类型都会被复制。

为了能够复制UPDATEDELETE操作,被发布的表必须配置有一个“复制标识”,这样在订阅者那一端才能标识对于更新或删除合适的行。默认情况下,复制标识就是主键(如果有主键)。也可以在复制标识上设置另一个唯一索引(有特定的额外要求)。如果表没有合适的键,那么可以设置成复制标识“full”,它表示整个行都成为那个键。不过,这样做效率很低,只有在没有其他方案的情况下才应该使用。如果在发布者端设置了“full”之外的复制标识,在订阅者端也必须设置一个复制标识,它应该由相同的或者少一些的列组成。如何设置复制标识的细节请参考REPLICA IDENTITY。如果在复制UPDATEDELETE操作的发布中加入了没有复制标识的表,那么订阅者上后续的UPDATEDELETE操作将导致错误。不管有没有复制标识,INSERT操作都能继续下去。

每一个发布都可以由多个订阅者。

Publication通过使用CREATE PUBLICATION命令创建并且可以在之后使用相应的命令进行修改或者删除。

表可以使用ALTER PUBLICATION动态地增加或者移除。ADD TABLE以及DROP TABLE操作都是事务性的,因此一旦该事务提交,该表将以正确的快照开始或者停止复制。

二、订阅

订阅是逻辑复制的下游端。订阅被定义在其中的节点被称为订阅者。一个订阅会定义到另一个数据库的连接以及它想要订阅的发布集合(一个或者多个)。

订阅者数据库的行为与任何其他PostgreSQL实例相同,并且可以被用作其他数据库的发布者,只需要定义它自己的发布。

如果需要,一个订阅者节点可以有多个订阅。可以在一对发布者-订阅者之间定义多个订阅,在这种情况下要确保被订阅的发布对象不会重叠。

每一个订阅都将通过一个复制槽接收更改。预先存在的表数据的初始数据同步过程可能会要求额外的临时复制槽。

逻辑复制订阅可以是同步复制的后备服务器。后备名称默认是该订阅的名称。可以在订阅的连接信息中用application_name指定一个可供选择的名称。

如果当前用户是一个超级用户,则订阅会被pg_dump转储。否则订阅会被跳过并且写出一个警告,因为非超级用户不能从pg_subscription目录中读取所有的订阅信息。

可以使用CREATE SUBSCRIPTION增加订阅,并且使用​​​​​​ALTERSUBSCRIPTION在任何时刻停止/继续订阅,还可以使用​​​​​​DROPSUBSCRIPTION删除订阅。

在一个订阅被删除并且重建时,同步信息会丢失。这意味着数据必须被重新同步。

模式定义不会被复制,并且被发布的表必须在订阅者上存在。只有常规表可以成为复制的目标。例如,不能复制视图。

表在发布者和订阅者之间使用完全限定的表名进行匹配。不支持复制到订阅者上命名不同的表。

表的列也通过名称匹配。允许在目标表中的列序不同,但是列类型必须匹配。目标表可以有被发布表没有提供的额外列。额外列将用其默认值填充。

2.1. 复制槽管理

如早前所提到的,每一个(活跃的)订阅会从远(发布)端上的一个复制槽接收更改。通常,远程复制槽是在使用CREATE SUBSCRIPTION创建订阅是自动创建的,并且在使用DROP SUBSCRIPTION删除订阅时,复制槽也会自动被删除。不过,在一些情况下,有必要单独操纵订阅以及其底层的复制槽。下面是一些场景:

  • 在创建一个订阅时,复制槽已经存在。在这种情况下,可以使用create_slot = false选项创建订阅并关联到现有的槽。

  • 在创建一个订阅时,远程主机不可达或者处于一种不明状态。在这种情况下,可以使用connect = false选项创建订阅。那么远程主机将根本不会被联系。这是pg_dump所使用的方式。这样,在订阅可以被激活之前,必须手工创建远程复制槽。

  • 在删除一个订阅时,复制槽应该被保留。当订阅者数据库正在被移动到一台不同的主机并且将从那里再被激活时,这种行为很有用。在这种情况下,可以在尝试删除该订阅之前,使用ALTER SUBSCRIPTION将复制槽解除关联。

  • 在删除一个订阅是,远程主机不可达。在这种情况下,可以在尝试删除该订阅之前,使用ALTER SUBSCRIPTION将复制槽解除关联。如果远程数据库实例不再存在,那么不需要进一步的行动。不过,如果远程数据库实例只是不可达,那么复制槽应该被手动删除。否则它将会继续保留WAL并且最终可能会导致磁盘被填满。这种情况应该要仔细地研究。

三、冲突

逻辑复制的行为类似于正常的DML操作,即便数据在订阅者节点本地被修改,逻辑复制也会根据收到的更改来更新数据。如果流入的数据违背了任何约束,复制将停止。这种情况被称为一个冲突。在复制UPDATEDELETE操作时,缺失的数据将不会产生冲突并且这类操作将被简单地跳过。

冲突将会产生错误并且停止复制,它必须由用户手工解决。在订阅者的服务器日志中可以找到有关冲突的详细情况。

通过更改订阅者上的数据(这样它就不会与到来的数据发生冲突)或者跳过与已有数据冲突的事务可以解决这种冲突。通过调用pg_replication_origin_advance()函数可以跳过该事务,函数的参数是对应于该订阅名称的node_name以及一个位置。复制源头的当前位置可以在pg_replication_origin_status系统视图中看到。

四、限制

逻辑复制当前有下列限制或者缺失的功能。这些可能在未来的发行中解决。

  • 数据库模式和DDL命令不会被复制。初始模式可以手工使用pg_dump --schema-only进行拷贝。后续的模式改变需要手工保持同步(不过值得注意的是,模式其实不需要在两端保持绝对相同)。当一个活跃的数据库中模式定义改变时,逻辑复制是鲁棒的:当模式在发布者上发生改变并且被复制的数据开始到达订阅者但却不适合表模式时,复制将报错,直至模式被更新。在很多情况下,可以通过先对订阅者应用额外的模式更改来避免间歇性的错误。

  • 序列数据不被复制。后台由序列支撑的serial或者标识列中的数据当然将被作为表的一部分复制,但是序列本身在订阅者上仍将显示开始值。如果订阅者被用作一个只读数据库,那么这通常不会是什么问题。不过,如果订阅者数据库预期有某种转换或者容错,那么序列需要被更新到最后的值,要么通过从发布者拷贝当前数据的防范(也许使用pg_dump),要么从表本身决定一个足够高的值。

  • 支持TRUNCATE命令的复制,但是在截断由外键连接在一起的表群体时必须要小心。在复制截断动作时,订阅者将截断与发布者上被截断的相同的表群体,这些表或者被明确指定或者通过CASCADE隐含地收集而来,然后还要减去不属于该订阅的表。如果所有受影响的表都属于同一个订阅,这会正确地工作。但是如果订阅者上要被截断的某些表有外键链接到不属于同一订阅的表,那么在订阅者上该截断动作的应用将会失败。

  • 大对象不会被复制。没有办法可以解决这个问题,除非把数据存储在普通表中。

  • 复制只能从基表到基表。也就是说,发布端和订阅端上的表都必须是普通表,而不是视图、物化视图、分区根表或者外部表。如果是分区,可以一一对应地复制分区层次,但当前不能复制成一种不同的分区设置。尝试复制不是基表的表将会导致错误。

五、架构

逻辑复制从拷贝发布者数据库上的数据库快照开始。拷贝一旦完成,发布者上的更改会在它们发生时实时传送给订阅者。订阅者按照数据在发布者上被提交的顺序应用数据,这样任意单一订阅中的发布的事务一致性才能得到保证。

逻辑复制被构建在一种类似于物理流复制的架构上。它由“walsender”和“apply”进程实现。walsender进程开始对WAL的逻辑解码并且载入标准逻辑解码插件(pgoutput)。该插件把从WAL中读取的更改转换成逻辑复制协议并且根据发布说明过滤数据。然后数据会被连续地使用流复制协议传输到应用工作者,应用工作者会把数据映射到本地表并且以正确的事务顺序应用它们接收到的更改。

订阅者数据库上的应用进程总是将session_replication_role设置为replica运行,这会产生触发器和约束上通常的效果。

逻辑复制应用进程当前仅会引发行触发器,而不会引发语句触发器。不过,初始的表同步是以类似一个COPY命令的方式实现的,因此会引发INSERT的行触发器和语句触发器。

5.1. 初始快照

已有的被订阅表中的初始数据会被快照并且以一种特殊类型的应用进程的并行实例进行拷贝。这种进程将创建自己的临时复制槽并且拷贝现有的数据。一旦现有的数据被拷贝完,工作者会进入到同步模式,主应用进程会流式传递在使用标准逻辑复制拷贝初始数据期间发生的任意改变,这会确保表被带到一种已同步的状态。一旦同步完成,该表的复制的控制权会被交回给主应用进程,其中复制会照常继续。

六、监控

因为逻辑复制是基于与物理流复制相似的架构的,一个发布节点上的监控也类似于对物理复制主节点的监控。

有关订阅的监控信息在pg_stat_subscription中可以看到。每一个订阅工作者在这个视图都有一行。一个订阅能有零个或者多个活跃订阅工作者取决于它的状态。

通常,对于一个已启用的订阅会有单一的应用进程运行。一个被禁用的订阅或者崩溃的订阅在这个视图中不会有行存在。如果有任何表的数据同步正在进行,对正在被同步的表会有额外的工作者。

七、安全性

用于复制连接的角色必须有REPLICATION属性(或者是一个超级用户)。该角色的访问必须被配置在pg_hba.conf中,并且它必须有LOGIN属性。

为了能够拷贝初始表数据,用于复制连接的角色必须在被发布的表上具有SELECT特权(或者是一个超级用户)。

要创建发布,用户必须在数据库中有CREATE特权。

要把表加入到一个发布,用户必须在该表上有拥有权。要创建一个自动发布所有表的发布,用户必须是一个超级用户。

要创建订阅,用户必须是一个超级用户。

订阅的应用过程将在本地数据库上以超级用户的特权运行。

特权检查仅在复制连接开始时被执行一次。在从发布者读到每一个更改记录时不会重新检查特权,在每一个更改被应用时也不会重新检查特权。

八、配置设置

逻辑复制要求设置一些配置选项。

wal_level = logical

在发布者端,wal_level必须被设置为logical,而max_replication_slots中设置的值必须至少是预期要连接的订阅数加上保留给表同步的连接数。max_wal_senders应该至少被设置为max_replication_slots加上同时连接的物理复制体的数量。

订阅者还要求max_replication_slots被设置。在这种情况下,它必须至少被设置为将被加入到该订阅者的订阅数。max_logical_replication_workers必须至少被设置为订阅数加上保留给表同步的连接数。此外,可能需要调整max_worker_processes以容纳复制工作者,至少为(max_logical_replication_workers + 1)。注意,一些扩展和并行查询也会从max_worker_processes中取得工作者槽。

九、快速设置

首先在postgresql.conf中设置配置选项:

wal_level = logical

对于一个基础设置来说,其他所需的设置使用默认值就足够了。

需要调整pg_hba.conf以允许复制(这里的值取决于实际的网络配置以及用于连接的用户):

host     all     repuser     0.0.0.0/0     md5

然后在发布者数据库上:

CREATE PUBLICATION mypub FOR TABLE users, departments;

并且在订阅者数据库上:

CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub;

上面的语句将开始复制过程,它会同步表users以及departments的初始表内容,然后开始复制对那些表的增量更改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cassandra 安装部署

文章目录 一、概述1.官方文档2. 克隆服务器3.安装准备3.1.安装 JDK 113.2.安装 Python3.3.下载文件 二、安装部署1.配置 Cassandra2.启动 Cassandra3.关闭Cassandra4.查看状态5.客户端连接服务器6.服务运行脚本 开源中间件 # Cassandrahttps://iothub.org.cn/docs/middleware/…

CI/CD笔记.Gitlab系列:2024更新后-设置GitLab导入源

CI/CD笔记.Gitlab系列 设置GitLab导入源 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_…

Spring Cloud + Nacos 集成Netty Socket.IO

项目需要集成实时消息通讯&#xff0c;所以尝试在项目中集成websocket。技术上选择了Socket.io&#xff0c;前/后端统一使用此开源项目来实现需求。 一、版本 spring cloud: 2022.0.4 注册中心&#xff1a; nacos Netty-Socket.io : 2.0.9 <dependency><groupI…

【C语言】InfiniBand驱动mlx4_register_interface函数

一、讲解 mlx4_register_interface函数是Mellanox InfiniBand驱动程序的一部分&#xff0c;这个函数的作用是注册一个新的接口(intf)到InfiniBand设备。这允许不同的子系统&#xff0c;如以太网或存储&#xff0c;能够在同一个硬件设备上注册它们各自需要的接口&#xff0c;在…

编程笔记 html5cssjs 008 HTML图片 名画欣赏

编程笔记 html5&css&js 008 HTML图片 名画欣赏 一、代码二、解释 这段HTML代码定义了一个网页&#xff0c;展示了名画欣赏的内容。主要包括页面的标题、样式定义和主体内容。其中&#xff0c;样式定义使用了CSS来控制页面的布局和外观&#xff0c;主体内容使用了结构化…

ASP.Net实现玩具管理(三层架构,两项数据相乘)

目录 演示功能&#xff1a; 点击启动生成页面 步骤&#xff1a; 1、建文件 ​编辑 2、添加引用关系 3、根据数据库中的列写Models下的XueshengModels类 4、DAL下的DBHelper&#xff08;对数据库进行操作&#xff09; 5、DAL数据访问层下的service文件 6、BLL业务逻辑层…

华为HCIE实验题库哪里有?Cloud相关证书咋样?

华为HCIE认证的含金量很高&#xff0c;这除了是因为华为自身的影响力之外&#xff0c;也是因为HCIE的考试难度大。 HCIE的实验考试长达八个小时&#xff0c;考的是实际操作和论述&#xff0c;要想拿下HCIE实验考试&#xff0c;不断练习是十分关键的。 而华为HCIE实验的题库哪…

通讯协议制定之交互方式、步骤介绍

文章目录 通讯协议制定之交互方式、步骤介绍1. 前言2. 通讯协议发送类型2.1 周期发送2.2 事件发送 3. 通讯协议数据包类型3.1 握手3.2 心跳3.1 数据包 4. 小结 通讯协议制定之交互方式、步骤介绍 1. 前言 通讯协议又称通信规程&#xff0c;是指通信双方对数据传送控制的一种约…

【Spring Boot 3】读取resource文件

【Spring Boot 3】读取resource文件 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或…

如何部署Python Flask并实现远程访问本地搭建web站点【内网穿透】

文章目录 前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程访问Flask的问答界面 前言 Flask是一个Python编写的Web微框架&#xff0c;让我们可以使用Python语言快速实现一个网站或Web服务&#xff0c;本期教程…

导出微软浏览器收藏的网页,并查看网页保存的登录密码

导出微软Edge浏览器收藏夹&#xff08;书签&#xff09;的步骤如下&#xff1a; 打开Microsoft Edge浏览器。右键点击浏览器收藏栏上的任意位置或使用快捷键Ctrl Shift O打开收藏夹管理页面。在收藏夹管理页面中&#xff0c;通常你会看到右上角或菜单区域有一个“…”或者三…

Axios中每次发送post请求前都会发送options请求

今天写前端的时候&#xff0c;发现每次post请求都会失败&#xff0c; 反复调试过后发现axios在每次发送post请求前都发送了options请求&#xff0c; 在网络搜罗了一大圈&#xff0c; 发现了原因是因为web页面发送了请求给vue后&#xff0c; vue再请求后端过程中发生了跨域&…

【算法】一维前缀和以及二维前缀和

目录 一维前缀和适用场景示例 二维前缀和适用场景一种情况另一种情况示例 一维前缀和 适用场景 求一段区间的和。 比如有一个数列 &#xff1a; 如果我们要求 [l,r]即某个区间内的数组和的时候&#xff0c;思路就是每遍历一个元素就进行求和&#xff0c;记录下加到al时的和…

Skywalking

1、简介 Skywalking是由国内开源爱好者吴晟开源并提交到Apache孵化器的开源项目&#xff0c; 2017年12月SkyWalking成为Apache国内首个个人孵化项目&#xff0c; 2019年4月17日SkyWalking从Apache基金会的孵化器毕业成为顶级项目&#xff0c; 目前SkyWalking支持Java、 .Net、 …

广告主投放系统从设计到实践

在当今数字广告行业中&#xff0c;广告主投放系统扮演着至关重要的角色。它是连接广告主和广告媒体之间的桥梁&#xff0c;帮助广告主实现广告投放目标并获得可观的回报。本篇博客文章将深入探讨广告主投放系统的设计和实践过程&#xff0c;并分享一些关键的经验和最佳实践。 …

flink的分组聚合、over聚合、窗口聚合对比

【背景】 flink有几种聚合&#xff0c;使用上是有一些不同&#xff0c;需要加以区分&#xff1a; 分组聚合&#xff1a;group agg over聚合&#xff1a;over agg 窗口聚合&#xff1a;window agg 省流版&#xff1a; 触发计算时机 结果流类型 状态大小 分组聚合group ag…

使用OpenCV实现两张图像融合在一起

简单介绍 图像融合技术是一种结合多个不同来源或不同传感器捕获的同一场景的图像数据&#xff0c;以生成一幅更全面、更高质量的单一图像的过程。这种技术广泛应用于遥感、医学影像分析、计算机视觉等多个领域。常见的图像融合技术包括基于像素级、特征级和决策级的融合方法&a…

基与HTML5的塔防游戏设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 项目背景与相关技术 3 1.1 背景与发展简介 3 1.2 HTML5技术及其优势 4 1.3 JavaScript开发的优势与劣势 4 1.4 CSS样式表在开发中的用处 5 1.5 本章小结 6 2 系统分析 7 2.1 需求分析 7 2.2 问题分析 7 2.3 流程设计 7 2.3 功能分析 8 2.…

数据分析入门,深入浅出的数据分析

时下正值大数据与人工智能高速发展的时刻&#xff0c;相信很多对数据分析感兴趣的朋友想要转行。很多朋友选择从事数据分析&#xff0c;主要是看到这个岗位的发展前景和薪资待遇。 但是一些小伙伴并不知道数据分析到底是做什么的&#xff1f;需要用到哪些知识&#xff1f; 为…

【Flink SQL】Flink SQL 基础概念:SQL Table 运行环境、基本概念及常用 API

Flink SQL 基础概念&#xff1a;SQL & Table 运行环境、基本概念及常用 API 1.SQL & Table 简介及运行环境1.1 简介1.2 SQL 和 Table API 运行环境依赖 2.SQL & Table 的基本概念及常用 API2.1 一个 SQL / Table API 任务的代码结构2.2 SQL 上下文&#xff1a;Tabl…