postgresql逻辑复制的实现

 更新时间:2025年06月16日 09:50:57   作者:24K老游  
本文介绍PostgreSQL逻辑复制实现,基于发布订阅模型,需设置WAL_LEVEL为logical,支持跨库备份,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

如果要将不同库的某关键表备份到指定库里,可以用逻辑复制完成相关功能。

逻辑复制基本概念

PG逻辑复制基于发布和订阅模型,一个发布可以有多个订阅者
发布publication可以创建在任意单机上,也可以在物理复制的主库上,发布端要求数据库参数WAL_LEVEL为logical。一个发布可以被多个数据库订阅。一个发布只能包含一个数据库中的表,但是这些表可以分布在不同的schema下。

订阅处于逻辑复制的下游端,一个订阅只能对应一个发布。订阅端的数据库名可以跟发布端不同,但是订阅发布的表名和schema必须相同

当订阅创建成功后,就会自动在发布端创建多个逻辑复制槽,其中一个用于后续的增量数据同步,永久保留,另外还会创建一个或者多个的临时复制槽,用于复制表的全量快照数据。
是当发布端是物理复制架构时,如果发生主从切换,发布是不会跟随数据库failover的。但是可以通过手工拷贝文件或者利用插件实现。

逻辑复制的限制

(1)数据库的表结构不会被复制,所以需要在订阅端先创建对应的schema和表
(2)TRUNCATE和DDL不会复制,如果要进行DDL变更,需要先在订阅端执行DDL,然后在发布端执行。
(3)Sequence不会不复制,当发布端使用了sequence数据,其写入了表的值会同步到订阅端,但是目标库的sequence并不会发生变化。
(4)不支持大对象。
(5)复制只能是基表到基表,不支持视图、物化视图、外部表等。如果表是分区表,需要基于分区进行复制。

测试

  • 发布和订阅端都新建相同的表t1,t2
  • 发布端为t1创建发布
  • 订阅端为t1创建订阅
新建一个库,做为订阅端
[pg@localhost data]$ pg_ctl init -D /data/db3

发布与订阅端都建相关同步结构的表t1,t2
postgres=# create table t1(id int,name varchar(20));
CREATE TABLE
postgres=# create table t2(id int,name varchar(20));
CREATE TABLE

在发布端为t1创建发布

修改发布端wal_level = logical,修改后要restart订阅端,reload不生效。
postgres=# show wal_level;
 wal_level
-----------
 logical
(1 row)


postgres=# create publication pub_test for table t1;
CREATE PUBLICATION

在订阅端为t1创建订阅

注:订阅端有wal_level也必须是logical

postgres=# create subscription sub_test connection 'host=127.0.0.1 port=15431 dbname=postgres user=pg' publication pub_test;
NOTICE:  created replication slot "sub_test" on publisher
CREATE SUBSCRIPTION

观察同步效果

在发布端分别向 t1 t2表插入数据
postgres=# insert into t1(id,name) values (1,'name1');
INSERT 0 1
postgres=# insert into t2(id,name) values (1,'name1');
INSERT 0 1

查看订阅端,只有已新建订阅的表数据同步
postgres=# select * from t1;
 id | name
----+-------
  1 | name1
(1 row)

postgres=# select * from t2;
 id | name
----+------
(0 rows)

为新表添加同步

发布端,将t2加入到发布
postgres=# alter publication pub_test add table t2;
ALTER PUBLICATION

查看发布表
postgres=# select * from pg_publication_tables;
 pubname  | schemaname | tablename
----------+------------+-----------
 pub_test | public     | t1
 pub_test | public     | t2
(2 rows)

订阅端,刷新订阅配置
postgres=# alter subscription sub_test refresh publication;
ALTER SUBSCRIPTION

发布端,分别向t1 t2插入数据
postgres=# insert into t1(id,name) values (2,'name2');
INSERT 0 1
postgres=# insert into t2(id,name) values (2,'name2');
INSERT 0 1

订阅端,查看t1 t2的数据
postgres=# select * from t1;
 id | name
----+-------
  1 | name1
  2 | name2
(2 rows)

postgres=# select * from t2;
 id | name
----+-------
  1 | name1
  2 | name2
(2 rows)

复制标识 REPLICA IDENTITY

REPLICA IDENTITY,复制标识,共有4种配置模式,分别为,

  • 默认模式(default):
    非系统表采用的默认模式,如果有主键,则用主键列作为身份标识,否则用完整模式。
  • 索引模式(index):将某一个符合条件的索引中的列,用作身份标识。
  • 完整模式(full):将整行记录中的所有列作为复制标识(类似于整个表上每一列共同组成主键)。
  • 无身份模式(nothing):不记录任何复制标识,这意味着UPDATE|DELETE操作无法复制到订阅者上。

表改复制标识可以通过ALTER TABLE进行修改。
ALTER TABLE T1 REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING};

T1没有主建,直接删除,提示需要设置 REPLICA IDENTITY
postgres=# delete from t1 where id=1;
ERROR:  cannot delete from table "t1" because it does not have a replica identity and publishes deletes
HINT:  To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.

修改为full,删除成功
postgres=# alter table t1 replica identity full;
ALTER TABLE
postgres=# delete from t1 where id=1;
DELETE 1

到此这篇关于postgresql 逻辑复制的实现的文章就介绍到这了,更多相关postgresql 逻辑复制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • PostgreSQL更新表时时间戳不会自动更新的解决方法

    PostgreSQL更新表时时间戳不会自动更新的解决方法

    这篇文章主要为大家详细介绍了PostgreSQL更新表时时间戳不会自动更新的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • PostgreSQL 用户名大小写规则小结

    PostgreSQL 用户名大小写规则小结

    PostgreSQL默认不区分用户名大小写,创建和连接时自动转为小写,使用双引号可强制区分,下面就来介绍一下PostgreSQL 用户名大小写规则,感兴趣的可以了解一下
    2025-06-06
  • postgresql分页数据重复问题的深入理解

    postgresql分页数据重复问题的深入理解

    这篇文章主要给大家介绍了关于postgresql分页数据重复问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用postgresql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • 基于Postgresql 事务的提交与回滚解析

    基于Postgresql 事务的提交与回滚解析

    这篇文章主要介绍了基于Postgresql 事务的提交与回滚解析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Postgresql数据库SQL字段拼接方法

    Postgresql数据库SQL字段拼接方法

    Postgresql里面内置了很多的实用函数,下面这篇文章主要给大家介绍了关于Postgresql数据库SQL字段拼接方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • PostgreSQL教程(十):性能提升技巧

    PostgreSQL教程(十):性能提升技巧

    这篇文章主要介绍了PostgreSQL教程(十):性能提升技巧,本文讲解了使用EXPLAIN、批量数据插入、关闭自动提交、使用COPY、 删除索引、删除外键约束等技巧,需要的朋友可以参考下
    2015-05-05
  • postgresql查询每个月的最后一天日期并对未查到的日期结果补0(操作示例)

    postgresql查询每个月的最后一天日期并对未查到的日期结果补0(操作示例)

    这篇文章主要介绍了postgresql查询每个月的最后一天日期,并对未查到的日期结果补0,pgsql需要使用函数使用date_trunc()函数找到指定月第一天,然后对该日期先加一个月在减一个月就能得到你传给的日期的最后一天日期,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • postgresql 实现更新序列的起始值

    postgresql 实现更新序列的起始值

    这篇文章主要介绍了postgresql 实现更新序列的起始值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Docker修改Postgresql密码的方法详解

    Docker修改Postgresql密码的方法详解

    在Docker环境中,对已运行的PostgreSQL数据库实例进行密码更改是一项常见的维护操作,下面将详述如何通过一系列命令行操作来实现这一目标,需要的朋友可以参考下
    2024-07-07
  • 如何获取PostgreSQL数据库中的JSON值

    如何获取PostgreSQL数据库中的JSON值

    这篇文章主要介绍了如何获取PostgreSQL数据库中的JSON值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01

最新评论