【转载】PostgreSQL逻辑订阅logical
原文地址:https://blog.csdn.net/gguxxing008/article/details/106356086
逻辑订阅是PostgreSQL10.0开始支持的新功能,PostgreSQL的物理流复制功能十分强大,在容灾、读写分离、HA等场景中都有广泛的使用,那么为什么还需要逻辑订阅呢?
我们先来看看物理流复制和逻辑订阅有哪些区别,主要有以下几点不同:
物理复制目前只能做到整个集群的复制。逻辑订阅可以做到针对某个对象
物理复制的备库只读,不能写入。逻辑订阅读写都可以
,逻辑订阅需要等待事务提交后,发布端才会使用wal_sender进程将decode后的数据发送给订阅端,订阅端流式接收与流式apply,因此逻辑订阅对主库性能影响较大
逻辑复制限制:
DDL不支持
序列数据不支持
大对象数据类型不支持
不支持视图,雾化视图,外部表
逻辑订阅实践:
在使用逻辑订阅之前我们需要对数据库进行一些配置:
发布端:
配置pg_hba.conf,允许订阅端通过流复制连接发布端
wal_level必须设置为logical
max_replication_slots 默认10个,根据情况修改。
发布端的角色必须具备replication权限,或者超级用户权限
订阅端:
创建subscription的用户,必须是超级用户
这些基本的一些准备做好之后,就可以开始配置逻辑订阅了:
1、配置发布端
postgres=# create table t1(id int primary key, info text, crt_time timestamp);
CREATE TABLE
postgres=# create publication testpub1 for table t1;
CREATE PUBLICATION
–查看当前数据库有哪些发布
postgres=# select * from pg_publication;
pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete
----------+----------+--------------+-----------+-----------+-----------
testpub1 | 10 | f | t | t | t
(1 row)
2、配置订阅端
postgres=# create table t1(id int primary key, info text, crt_time timestamp); --不定义主键 DML会报错
CREATE TABLE
postgres=# create subscription testsub1 connection 'hostaddr=172.18.10.16 port=5432 user=postgres dbname=d2' publication testpub1 with (enabled, create_slot, slot_name='sub1_from_pub1');
NOTICE: created replication slot "sub1_from_pub1" on publisher
CREATE SUBSCRIPTION
–查看有哪些订阅
postgres=# select * from pg_subscription ;
subdbid | subname | subowner | subenabled | subconninfo | subslotname | subsynccommit | subpublications
---------+----------+----------+------------+----------------------------------------------------------------+----------------+---------------+-----------------
16401 | testsub1 | 10 | t | hostaddr=192.168.7.177 port=1921 user=postgres dbname=postgres | sub1_from_pub1 | off | {testpub1}
(1 row)
postgres=# select * from pg_stat_subscription ;
subid | subname | pid | relid | received_lsn | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time
-------+----------+------+-------+--------------+-------------------------------+-------------------------------+----------------+-------------------------------
44943 | testsub1 | 7877 | | 1/76119308 | 2019-09-10 13:20:07.497634+08 | 2019-09-11 01:23:39.104443+08 | 1/76119308 | 2019-09-10 13:20:07.497634+08
(1 row)
数据库插入测试:
–发布端:
postgres=# insert into t1 select t,md5(random()::text),clock_timestamp() from generate_series(1,1000) t;
INSERT 0 1000
然后我们去订阅端查看:
postgres=# select count(*) from t1;
count
-------
100
(1 row)
这里需要注意,目前逻辑订阅不支持DDL语句的同步(pg12开始支持),例如:
–发布端:
postgres=# truncate t1;
TRUNCATE TABLE
再去订阅端查看,数据库还是没有变化
postgres=# select count(*) from t1;
count
-------
1000
(1 row)
因为逻辑订阅实际上和MySQL binglog复制类似,但是DDL是不写表的,那么DDL如何复制呢?
比较简单的一种方法就是:将DDL记录下来,写入表中,在订阅端对这个表创建触发器,在触发器内执行DDL即可。需要被订阅的对象,建上对应的触发器即可。总的来说,PostgreSQL的逻辑订阅目前还是有限局限性,并且和物理流复制相比性能差距较明显,但是对于在某些物理流复制无法实现的场景,使用逻辑订阅还是能够起到很大的作用!
补充几个测试结论:
1、发布端和订阅端的表在没有启用任何约束和索引的情况下,发布端只能写入数据,不能更新,更新会报如下错误:
d1=# update t44 set name='aa' where id =1;
ERROR: cannot update table "t44" because it does not have a replica identity and publishes updates
HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
2、消除以上错误一种是在发布端和订阅端的表上添加主键,二种添加唯一索引,在添加replica identify,如果还是不行需要删除发布端再重新建立生效。
create unique index idex_t44_name on t44(name);
alter table t44 replica identity using index idex_t44_name;
Logical Decoding测试补充:
测试前需要先设置2个参数:
wal_level=logical,需要重启
max_replication_slots 默认10个,根据情况修改。
1、创建一个复制槽,名称为logical_slot,使用插件:test_decoding
2=# SELECT pg_create_logical_replication_slot('logical_slot', 'test_decoding'); --物理复制用的是pg_create_physical_replication_slot('test_slot');
pg_create_logical_replication_slot
------------------------------------
(logical_slot,2/F003C6A8)
(1 row)
2、查看当前复制槽状态
d2=# select * from pg_replication_slots where slot_name='logical_slot';
-[ RECORD 1 ]-------+--------------
slot_name | logical_slot
plugin | test_decoding
slot_type | logical
datoid | 65249
database | d2
temporary | f
active | f
active_pid |
xmin |
catalog_xmin | 379478
restart_lsn | 2/F003C670
confirmed_flush_lsn | 2/F003C6A8
3、执行过insert看下效果,我们的insert已经被解析出来
d2=# insert into t1 values(1,'a');
INSERT 0 1
d2=# SELECT * FROM pg_logical_slot_peek_changes('logical_slot', NULL, NULL);
lsn | xid | data
------------+--------+--------------------------------------------------------------------
2/F003C6A8 | 379482 | BEGIN 379482
2/F003C6A8 | 379482 | table public.t1: INSERT: id[integer]:1 name[character varying]:'a'
2/F003C7A8 | 379482 | COMMIT 379482
(3 rows)
4、再执行个ddl
d2=# create table t2(id int,name varchar(10));
CREATE TABLE
d2=#
d2=#
d2=# SELECT * FROM pg_logical_slot_peek_changes('logical_slot', NULL, NULL);
lsn | xid | data
------------+--------+--------------------------------------------------------------------
2/F003C6A8 | 379482 | BEGIN 379482
2/F003C6A8 | 379482 | table public.t1: INSERT: id[integer]:1 name[character varying]:'a'
2/F003C7A8 | 379482 | COMMIT 379482
2/F003C810 | 379483 | BEGIN 379483
2/F00544C0 | 379483 | COMMIT 379483
(5 rows)
这里只看到了事务的开始和结束,但是无法看到ddl操作
5、消费逻辑复制槽后的变化
d2=# SELECT * FROM pg_logical_slot_get_changes('logical_slot', NULL, NULL);
lsn | xid | data
------------+--------+----------------------------------------------------------------------
2/F003C6A8 | 379482 | BEGIN 379482
2/F003C6A8 | 379482 | table public.t1: INSERT: id[integer]:1 name[character varying]:'a'
2/F003C7A8 | 379482 | COMMIT 379482
2/F003C810 | 379483 | BEGIN 379483
2/F00544C0 | 379483 | COMMIT 379483
2/F00544F8 | 379484 | BEGIN 379484
2/F00544F8 | 379484 | table public.t2: INSERT: id[integer]:21 name[character varying]:'2a'
2/F0054568 | 379484 | COMMIT 379484
(8 rows)
d2=#
d2=# SELECT * FROM pg_logical_slot_get_changes('logical_slot', NULL, NULL); --无法二次消费
lsn | xid | data
-----+-----+------
(0 rows)
d2=#
d2=# SELECT * FROM pg_logical_slot_peek_changes('logical_slot', NULL, NULL); --change内没有内容
lsn | xid | data
-----+-----+------
(0 rows)
5、删除复制槽
postgres=# SELECT pg_drop_replication_slot('logical_slot');
pg_drop_replication_slot
--------------------------
(1 row)
解读
逻辑复制使用复制槽和解码插件来发送数据库中的操作,并转成人们可以理解的格式。
pg_logical_slot_get_changes和pg_logical_slot_peek_changes 的区别是前者消费这些changes,而后者以只读的方式查看,而不会remove。
以下这些插件可以使用:
test_decoding – the default plugin;
wal2json – shows the changes in JSON format ;
decoder_raw – reconstructs the query that has applied the change.
decoderbufs, 一个PostgreSQL逻辑解码器输出插件,用于将数据作为协议缓冲区传送
ali_decoding 阿里巴巴研发的
————————————————
版权声明:本文为CSDN博主「gguxxing008」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gguxxing008/article/details/106356086
【转载】PostgreSQL逻辑订阅logical的更多相关文章
- PostgreSQL逻辑订阅
测试环境:PostgreSQL 13.2 1.逻辑订阅简介 由于物理复制只能做到这个集群的复制,不能正对某个对象(表)进行复制,且物理复制的备库只能读,不能写.相反,逻辑订阅同时支持主备库读写,且可以 ...
- PostgreSQL逻辑复制使用记录
之前逻辑复制刚刚出来的时候就使用过,但是没有进行整理,这次一个项目需要逻辑复制的自动迁移,再次拾起逻辑复制. 在此之前有两个疑问: 1)同一个表,既有流复制,又有逻辑复制,这样数据会有两份吗? --不 ...
- PostgreSQL逻辑复制之pglogical篇
PostgreSQL逻辑复制之slony篇 一.pglogical介绍 pglogical 是 PostgreSQL 的拓展模块, 为 PostgreSQL 数据库提供了逻辑流复制发布和订阅的功能. ...
- Windows 环境搭建 PostgreSQL 逻辑复制高可用架构数据库服务
本文主要介绍 Windows 环境下搭建 PostgreSQL 的主从逻辑复制,关于 PostgreSQl 的相关运维文章,网络上大多都是 Linux 环境下的操作,鲜有在 Windows 环境下配置 ...
- PostgreSQL逻辑复制之slony篇
Slony是PostgreSQL领域中最广泛的复制解决方案之一.它不仅是最古老的复制实现之一,它也是一个拥有最广泛的外部工具支持的工具,比如pgAdmin3.多年来,Slony是在PostgreSQL ...
- PostgreSQL逻辑复制解密
在数字化时代的今天,我们都认同数据会创造价值.为了最大化数据的价值,我们不停的建立着数据迁移的管道,从同构到异构,从关系型到非关系型,从云下到云上,从数仓到数据湖,试图在各种场景挖掘数据的价值.而在这 ...
- PostgreSQL逻辑复制槽
Schema | Name | Result data type | Argument data types | Type ------------+------------------------- ...
- 转载:逻辑回归的python实现
转载自:http://blog.csdn.net/zouxy09/article/details/20319673 一.逻辑回归(LogisticRegression) Logistic regres ...
- PostgreSQL逻辑复制到kafka-实践
kafka 安装 wget http://mirror.bit.edu.cn/apache/kafka/2.3.0/kafka_2.12-2.3.0.tgz cp kafka_2.12-2.0.1.t ...
- postgresql逻辑备份工具pg_dump和pg_resotre学习
(一)pg_dump备份 pg提供了pg_dump和pg_dumpall命令进行数据库的备份,pg_dumpall是将整个pg集群转储到一个脚本文件中,而pg_dump命令可以选择一个数据库或者部分表 ...
随机推荐
- Docker 详解
1.docker 基础 https://blog.csdn.net/huangjhai/article/details/118854733 2.docker进阶 https://blog.csdn.n ...
- hover状态下改变图片颜色的方式 悬停图片切换;css变量;悬停svg图片改变颜色;VUE
由外部json文件,按照配置方式引入图片路径时,需要一些值得注意的语法来动态引入和改变图片 1.图片路径设置 ,按照img标签动态引入图片 <img src=''/> 路径不引入变量,此时 ...
- 4K60帧!RayLink远程控制软件如何帮助设计师远程办公?
司机在家能远程工作吗?大写的"能"!!!如果你听说过司机远程办公,那你一定对下面这张图不陌生~ (远程办公的叉车司机) 这张图展示的是负责在库房工作的叉车司机在非办公区域远程办公的 ...
- css布局、动画要点
background属性 属性解释background属性是css中应用比较多,且比较重要的一个属性,它是负责给盒子设置背景图片和背景颜色的,background是一个复合属性,它可以分解成如下几个设 ...
- 原因代码: 0x2000c 关机类型: 关机
进程 C:\Windows\system32\silsvc.exe (XTKFSERVER2019) 由于以下原因已代表用户 NT AUTHORITY\SYSTEM 启动计算机 XTKFSERVER2 ...
- mixup: BEYOND EMPIRICAL RISK MINIMIZATION概述
参考简书,github 0.前言 相关资料: arxiv github 论文解读 论文基本信息: 领域:数据增强 发表时间:arxiv 2022(2022.5.1) 1.针对的问题 大型的深度神经网络 ...
- 项目中pom.xml的某些坐标无法加载
项目中pom.xml的某些坐标无法加载 maven官方查找对应的坐标文件下载 https://mvnrepository.com/artifact/com.fasterxml.jackson.core ...
- python 统计 excel 表格中文件总大小
需求:统计excel 表格中文件总大小 表格内容,包含Mi.Gi.KB 96.73Mi 95.89Mi 6.89Gi 6.75Gi 10.00KB 统计总大小代码,目标是将Gi.KB换算成 Mi,然后 ...
- 记一次SpringBoot整合Redis的Bug
SpringBoot整合Redis遇见的坑 <!--Redis配置开始--> <dependency> <groupId>org.springframework.b ...
- 2022-3-14内部群每日三题-清辉PMP
1.开发一款银行零售业务新产品的项目正在进行中,由于团队成员缺乏激励,该项目落后于进度.项目经理应该如何激励项目团队? A.提供认可与奖励 B.使用教练和指导技能 C.委托职责 D.应用创造性的问题解 ...