postgresql复制标识问题

问题:
pgsql数据库报错:

 ERROR: cannot delete from table "xxxxx" because it does not have a replica identity and publishes update

解决方法:

ALTER TABLE xxxxx REPLICA IDENTITY FULL;

原因分析:
当前度娘搜到的最多的是“PostgreSQL不喜欢缺少复制主键的表,即使是临时表”,也是来自于一个网友的帖子
在这里插入图片描述
由于对postgresql数据的原理不太理解,所有对这个回复还是比较懵逼的,所有就查询整理了一下postgresql数据库复制的相关内容;

===postgresql逻辑复制-复制标识
逻辑复制(Logical Replication),是一种根据数据对象的 复制标识(Replica Identity)(通常是主键)复制数据对象及其变化的方法。
逻辑复制 这个术语与 物理复制相对应,物理复制使用精确的块地址与逐字节复制,而逻辑复制则允许对复制过程进行精细的控制。

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

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

这个业务逻辑使用场景还是比较多得,平时在工作中也有同样的使用场景,需要实时监控数据库数据的变化,例如:数据库与缓存(redis)数据的一致性,数据库中的数据变更要同步到缓存中,可能很多通过采用的方式是通过主动查询的形式不断查询数据库进行判断数据是否存在变更,这样对性能消耗比较大,实时性有延迟,并且逻辑比较复杂,postgresql数据库复制逻辑就能在数据同步时实现被动通知的模式,实时性高、资源请求次数少;
类似于阿里开发的canal工具,用于订阅通知mysql数据库的变更数据,阿里的PolarDB PostgreSQL和腾讯的DIP都支持postgresql数据库数据的订阅功能,有兴趣的可以了解一下,本人也会在后续的文章中整理postgresql发布订阅的方式,因为我们也经常在工作中用到获取postgresql变更数据的场景;

复制标识:

1)为了能够复制UPDATE和DELETE操作,被发布的表必须配置有一个复制标识
,这样在订阅者那一端才能标识对于更新或删除合适的行。

2)默认情况下,复制标识就是主键(如果有主键)。也可以在复制标识上设置另一个唯一索引(有特定的额外要求)。如果表没有合适的键,那么可以设置成复制标识“full”,它表示整个行都成为那个键。不过,这样做效率很低,只有在没有其他方案的情况下才应该使用。

3)如果在发布者端设置了“full”之外的复制标识,在订阅者端也必须设置一个复制标识,它应该由相同的或者少一些的列组成。

4)如果在复制UPDATE或DELETE操作的发布中加入了没有复制标识的表,那么订阅者上后续的UPDATE或DELETE操作将导致错误。不管有没有复制标识,INSERT操作都能继续下去。

复制标识支持以下几种类型:主键、唯一索引、FULL(整行数据)

--主库删除'AAA'
hr=> delete from jobs where job_id='AAA';
ERROR:  cannot delete from table "jobs" because it does not have a replica identity and publishes deletes
HINT:  To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.

REPLICA IDENTITY建议设置成主键。PG这样做可以避免很多风险,在 MySQL进行主从复制时,有时会出现主从延迟,通常是由于没有主键或没有索引导致操作缓慢。而PG直接告诉你,如果没有REPLICA IDENTITY
,就不能进行delete和update同步。因此就不会发生更新或删除缓慢的情况。如未设定主键也可直接使用REPLICA IDENTITY FULL
。在FULL的情况下,所有列的值始终被写入WAL。这是最消耗资源的模式。我们这里只是演示,如果是大量更新删除的表,建议不要使用FULL。

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

复制身份与索引的正确配置
表上的复制标识配置,与表上有没有索引是两件独立的事。尽管各种排列组合都是可能的,然而在实际使用中只有三种可行的情况,其他情况都无法正常完成逻辑复制的功能(如果不报错,通常也是侥幸)
1)表上有主键,使用默认的 default 复制标识,不需要额外配置。
2)表上没有主键,但是有非空唯一索引,显式配置 index 复制标识。
3)表上既没有主键也没有非空唯一索引,显式配置full复制标识(运行效率低,仅作为兜底方案)
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PostgreSQL主从复制是一种常见的数据库复制技,用于实现数据的冗余备份和读写分离。在主从复制中,一个主数据库(Master)负责处理写操作,而一个或多个从数据库(Slave)则负责接收主数据库的变更并进行复制。 以下是PostgreSQL主从复制的基本原理和步骤: 1. 配置主数据库:在主数据库上,需要修改postgresql.conf文件和pg_hba.conf文件。其中,postgresql.conf文件中需要设置wal_level为replica,max_wal_senders为允许的最大连接数,以及设置archive_mode为on。pg_hba.conf文件中需要添加允许从数据库连接的配置。 2. 创建复制用户:在主数据库上,创建一个用于复制的用户,并赋予REPLICATION角色。 3. 备份主数据库:在主数据库上执行pg_basebackup命令,将主数据库的数据目录备份到从数据库。 4. 配置从数据库:在从数据库上,同样需要修改postgresql.conf文件和pg_hba.conf文件。其中,postgresql.conf文件中需要设置standby_mode为on,并指定recovery.conf文件的位置。pg_hba.conf文件中需要添加允许主数据库连接的配置。 5. 创建recovery.conf文件:在从数据库上创建recovery.conf文件,并设置primary_conninfo参数为主数据库的连接信息。 6. 启动从数据库:在从数据库上启动PostgreSQL服务,它将自动连接到主数据库并开始复制数据。 7. 监控复制状态:可以使用pg_stat_replication视图来监控主从复制的状态,包括复制延迟和连接状态等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dylan~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值