前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >活学活用 PostgreSQL 逻辑复制实现 I U D 历史记录

活学活用 PostgreSQL 逻辑复制实现 I U D 历史记录

作者头像
AustinDatabases
发布于 2019-09-24 08:58:29
发布于 2019-09-24 08:58:29
65900
代码可运行
举报
文章被收录于专栏:AustinDatabasesAustinDatabases
运行总次数:0
代码可运行
有些数据库是有历史表的功能的,也就是你操作的数据的历史会记录到另一个表中,包含更新的和删除的记录,以防止某些意外的情况找回历史的数据,或知道在什么时候表中的记录变化。

PostgreSQL 本身没有这样的功能的,但这里有一个想法可以来通过逻辑复制的方法来模拟这样的功能。当然通过trigger 也是可以完成这样的功能,但是考虑到可能会有遇上性能上的问题。

这里我们在test 数据库上建立log_save的表,我们的需求是通过逻辑复制的功能,将log_save 的插入的记录,update 的记录 都进行一个保留(update 只能保存最后一次修改的记录),并且通过某些SQL 的方式也能追踪到这个表到底删除了那些记录。

大致的思路,我们建立三张复制的表在不同的数据库中(因为复制的表名必须一致,三个数据库分别是 test_insert test_update test_delete),第一张仅仅记录 log_save 表的insert 记录,包含一个时间戳,同时另外两张表一个记录 insert,update 的记录,最后一张记录 insert delete的操作。

create publication log_save_insert for table public.log_save with (publish = 'insert');

create publication log_save_update for table public.log_save with (publish = 'insert,update');

create publication log_save_delete for table public.log_save with (publish = 'insert,delete');

创建三个数据库 test_insert test_update test_delete

先添加3张历史表,分别建立在不同的数据库中,每个库一张

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE public.log_save
test-# (
test(#     id serial,
test(#     log_type character varying(10),
test(#     log_content text,
test(#     insert_date timestamp without time zone,
test(#     PRIMARY KEY (id)
test(# )
test-# WITH (
test(#     OIDS = FALSE,
test(#     FILLFACTOR = 80,
test(#     autovacuum_enabled = TRUE
test(# );
alter table log_save add column date_time timestamp default now();

数据库中创建逻辑复制槽 (可以仅仅创建一个复制槽即可,这里为了让下面的操作更清晰,生成了三个复制槽)

创建逻辑复制槽

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 SELECT * FROM pg_create_logical_replication_slot('log_save_insert', 'pgoutput');
 SELECT * FROM pg_create_logical_replication_slot('log_save_delete', 'pgoutput');
 SELECT * FROM pg_create_logical_replication_slot('log_save_update', 'pgoutput');

创建订阅,在三个不同的库中每个库对应不同的publication 创建一个订阅

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE SUBSCRIPTION log_save_insert CONNECTION 'host=192.168.198.123 dbname=test user=repl password=123456 port=5432' PUBLICATION log_save_insert with (create_slot = false,slot_name = log_save_insert);
CREATE SUBSCRIPTION log_save_update CONNECTION 'host=192.168.198.123 dbname=test user=repl password=123456 port=5432' PUBLICATION log_save_update with (create_slot = false,slot_name = log_save_update);
CREATE SUBSCRIPTION log_save_delete CONNECTION 'host=192.168.198.123 dbname=test user=repl password=123456 port=5432' PUBLICATION log_save_delete with (create_slot = false,slot_name = log_save_delete);

下面我们可以做一个实验

我们在 test 数据库中的表 log_save 插入数据,然后更改数据,删除数据

下面是初始的数据

现在我们删除 ID = 19 的数据

我们在查看test_delete 的数据库 的log_save 表 我看可以看到,的确数据少了

我们在修改ID = 17 列 log_content 的数据,可以很清晰的看到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
update log_save set log_content = '09899', insert_date = now() where id = 17;

以上已经验证了,三个库中的 insert update delete 操作是针对三种操作,通过这些表我们可以做什么

1 检索,检索今天log_save 插入多少数据库

2 今天log_save 表到底更新了多少行数据,那些行被更新过 (这里默认在update 里面的insert_date 为null的是没有更新过的数据,当然你也可以设置成其他的方式,例如插入的时候带有insert_date ,而update 操作不更新insert_date ,这样 update的表中的insert_date 和insert 表的 insert_date 就会不同)

这里采用上面说的insert_date 为空的说明没有更新

3 最后我们是要获得今天到底删除了多少记录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select count(id) from log_save where id not in (
select id from (
select id from dblink ('host=192.168.198.123 dbname=test_delete user=repl password=123456','select id from log_save') 
as b(id int) ) as b) ;

以上的查询比较粗糙,不过基本上大致的基础工作都做完了。

通过上面的例子,我们可以对一个数据库的所有的表都可以进行类似历史方面的记录统计,和数据的历史记录,通过一些查询可以找到误删除的数据,或者误更新的数据。当然上面说过其实通过 trigger 的方式也是可以完成这样的工作的,但是在性能方面的影响不言而喻。如果是对一个库的所有的表都进行这样的设置,trigger 的方式显然也是不合适的。并且在分析数据的时候还会对基表产生性能影响。

其实如果对数据库的某些特殊的功能熟悉后,通过这些功能可以演化出很多通过程序很难完成的功能,例如是否可以通过表继承的方式来每天生成一个一个表的一天的记录。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PostgreSQL 逻辑复制一网打尽
PostgreSQL 的逻辑复制的场景还是蛮多的,尤其在一些需要进行关键数据表数据同步的情况下,将数据操作进行同步是十分有必要的业务场景。在提到POSTGRESQL的逻辑复制之前,还是的先说说逻辑复制的应用场景,以及与物理复制的不同和操作中的注意事项。
AustinDatabases
2021/11/17
8860
PostgreSQL 逻辑复制一网打尽
聊聊PostgreSQL的Replication
CAP理论 consistency:在整个集群角度来看,每个节点是看到的数据一致的;不能出现集群中节点出现数据不一致的问题 vailability:集群中节点,只有有一个节点能提供服务 partitioning:集群中的节点之间网络出现问题,造成集群中一部分节点和另外一部分节点互相无法访问 基本术语 Master节点:提供数据写的服务节点 Standby节点:根据主节点(master节点)数据更改,这些更改同步到另外一个节点(standby节点) Warm Standby节点:可以提升为master节点的s
用户4700054
2022/08/17
1.5K0
聊聊PostgreSQL的Replication
POSTGRESQL 逻辑复制与CDC捕捉构建实时数据分析平台
大部分数据库都提供CDC 的功能, change data capture, DB的同学可能要问,为什么要这个功能, ORACLE 有DG 数据复制, SQL SERVER 有replication , MYSQL 有 binlog 复制, PG 逻辑,物理复制都有,CDC是不是多余的.
AustinDatabases
2020/07/30
1.4K0
POSTGRESQL 逻辑复制与CDC捕捉构建实时数据分析平台
POSTGRESQL 逻辑复制槽,what when how ,check and monitor 这一篇
postgresql 的逻辑复制槽估计是一个被说烂的话题,但如果你是在大批量的使用逻辑复制槽作为数据的同步和复制的功能,那这就是一个另外的话题了。
AustinDatabases
2022/04/05
3.5K0
POSTGRESQL 逻辑复制槽,what  when  how ,check and monitor  这一篇
PostgreSQL 逻辑复制的“水”还是深
接上期的问题,在删除postgresql的 逻辑复制时遇到了一些麻烦,删除subscription时遇到了
AustinDatabases
2019/09/19
1.4K0
PostgreSQL 逻辑复制的“水”还是深
PostgreSQL逻辑复制槽功能
PostgreSQL 数据库的逻辑复制槽是一项非常重要的功能,通过逻辑复制槽本身,可以提供多种多样的功能。这里我们画一个思维导图进行一个全方面的分析和梳理。
AustinDatabases
2025/03/18
840
PostgreSQL逻辑复制槽功能
PostgreSQL主从复制--逻辑复制
逻辑复制是基于逻辑解析,其核心原理是逻辑主库将Publication中表的WAL日志解析成一定格式并发送给逻辑备库,逻辑备库Subscription接收到解析后的WAL日志后进行重做,从而实现表数据同步。
俊才
2019/10/14
4.6K0
PostgreSQL主从复制--逻辑复制
--PostgreSQL 的存储过程怎么写 与 质疑
PostgreSQL 的存储过程在POSTGRESQL 11 有了改变,从统一的 create function 到 create procedure 到底能从中获得什么
AustinDatabases
2019/10/29
3.9K0
PostgreSQL 逻辑复制"水”好深
逻辑复制,就是那个容易出错,效率低,容易造成主从数据不一致的技术. 可能在提及逻辑复制,就会得到上面的评论,或许是MYSQL 给人的第一印象(其实我不认为逻辑复制有多不好)。当然对比物理复制 Stream Replication 来说,逻辑的复制的效率的确是不高,并且上面被吐槽的地方都是有的。
AustinDatabases
2019/09/18
1.4K0
PostgreSQL 逻辑复制"水”好深
PostgreSQL逻辑复制之pglogical篇
pglogical 是 PostgreSQL 的拓展模块, 为 PostgreSQL 数据库提供了逻辑流复制发布和订阅的功能。 pglogical 重用了 BDR 项目中的一部分相关技术。pglogical 是一个完全作为PostgreSQL 扩展实现的逻辑复制系统。完全集成,它不需要触发器或外部程序。这种物理复制的替代方法是使用发布/订阅模型复制数据以进行选择性复制的一种高效方法。支持 PG10、9.6、9.5、9.4 ,提供比 Slony、Bucardo 或 Londiste 更快的复制速度,以及跨版本升级。 我们使用的下列术语来描述节点和数据流之间的关系,重用了一些早期的 Slony 技术中的术语:
星哥玩云
2022/08/18
2.2K0
Python的轻量级ORM框架peewee
在前面的《改变python对象规则的黑魔法metaclass》一文中,我介绍了使用metaclass自己编写ORM框架的思路。
快学Python
2021/08/09
5.5K0
PostgreSQL 逻辑复制数据不一致,导致主库wal log 无限增大
1 灵活: 逻辑复制对比物理复制来说,可以单表进行数据的复制,物理复制则是不可以的,并且大部分时间对于ETL的功能需求来说,物理复制太重了,需要的磁盘,网络,等资源都相对于逻辑复制消耗的要大的多.
AustinDatabases
2020/07/30
1.5K0
TBase-手工创建数据多活
利用数据多活同步mc.public.test_repl到postgres.public.test_repl的数据。
腾讯云数据库 TencentDB
2020/12/07
7690
PG Logical Replication 逻辑复制
我下面演示的PG环境是单机多实例的方式部署在同一台物理机上的。部署方式可以参考 上一篇博客。
保持热爱奔赴山海
2019/09/17
1.6K0
PostgreSQL PG16 逻辑复制在STANDBY 上工作 (译)
Postgres 16刚刚发布了测试版,我对其中的新功能非常兴奋。该新功能允许从待命服务器进行逻辑复制,用户可以:
AustinDatabases
2023/09/06
9190
PostgreSQL  PG16 逻辑复制在STANDBY 上工作  (译)
PostgreSQL13.0流复制尝鲜
postgresql13.0于2020年9月21日正式发布,话说现在pg的大版本从10开始发生了变化,以第一个数字代表一个大版本更新,而9之前的版本则是以9.1->9.2->9.x这样代表大版本更新。所以现在看起来pg的更新好像越来越快了,每个版本其实更新的内容不是很多。13发布后下载来了源码尝尝鲜,源码编译上没有什么改变,依旧很简单很亲和,四条简单的命令完成编译安装,对平台兼容性也很好。
数据库架构之美
2021/02/26
8550
PostgreSQL13.0流复制尝鲜
Postgresql主从复制
Postgresql主从复制 主备数据库启动,备库启动wal_receiver进程,wal进程向主库发送连接请求; 主库收到连接请求后启动wal_sender进程,并与wal_receiver进程建立tcp连接; 备库wal_receiver进程发送最新的wal lsn 给主库; 主库进行lsn 对比,定期向备库发送心跳信息,来确认备库的可用性,并且将没有传递的wal日志文件进行发送,同时调用SyncRepWaitForLSN()函数来获取锁存器,并且等待备库响应;锁存器的释放时机和主备同步模式的选择有
用户7353950
2022/05/11
8620
Postgresql主从复制
PostgreSQL逻辑复制之slony篇
Slony是PostgreSQL领域中最广泛的复制解决方案之一。它不仅是最古老的复制实现之一,它也是一个拥有最广泛的外部工具支持的工具,比如pgAdmin3。多年来,Slony是在PostgreSQL中复制数据的惟一可行的解决方案。Slony使用逻辑复制;Slony-I一般要求表有主键,或者唯一键;Slony的工作不是基于PostgreSQL事务日志的;而是基于触发器的;基于逻辑复制高可用性;PostgreSQL除了slony;还有Londiste,BDR等等后续文章会讲到
星哥玩云
2022/08/16
5980
PostgreSQL逻辑复制之slony篇
PostgreSQL 通过python 监控逻辑复制
本期是通过PYTHON 来对逻辑复制中的配置参数,publication 定义, 打印不适合进行逻辑复制的表,打印没有在使用的复制槽,另外包含当前发布端和接收端两边的LSN对比。
AustinDatabases
2021/11/17
8010
PostgreSQL 通过python 监控逻辑复制
PostgreSQL 13、14中逻辑复制/解码改进
https://www.percona.com/blog/how-patroni-addresses-the-problem-of-the-logical-replication-slot-failover-in-a-postgresql-cluster/
yzsDBA
2022/03/29
7670
相关推荐
PostgreSQL 逻辑复制一网打尽
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验