PostgreSQL 逻辑复制"水”好深

  • 2019 年 10 月 5 日
  • 筆記

逻辑复制,就是那个容易出错,效率低,容易造成主从数据不一致的技术. 可能在提及逻辑复制,就会得到上面的评论,或许是MYSQL 给人的第一印象(其实我不认为逻辑复制有多不好)。当然对比物理复制 Stream Replication 来说,逻辑的复制的效率的确是不高,并且上面被吐槽的地方都是有的。

但逻辑复制有什么好

1 我只要XX 库的数据 ,或XX表的数据,物理复制可以吗?

2 我要做汇聚库,要 XX 库表 XX 库表 到 一个库中,进行数据分析?

3 诶,我复制的库的数据,可能的改改,在从库上改改试试,那我改的时候你就别在复制了,我改完做完测试后,在还原我刚才改的数据,你在继续复制OK ?

4 诶,我们要将目前的PG 10 的表复制到PG 11

那物理复制——– NO WAY

所以一项技术的好坏先要看他是否能满足需求,所以逻辑复制好不好要看他是否能满足上面的需求。

OK 我们先来将一个测试库导入到 PG 的数据库中,大家如果测试可以使用dvdrental 库作为 simple 库。

我们举例下面就是我们要操作的数据库 dvdrental 中包含了15个表

1 我们将dvdrental 整体数据库中的所有的表都复制到另一个PG的服务器中。

1 创建一个publication,在 dvdrental 数据库中执行如下命令创建一个 dvdrental 为命名的所有表的 publication

CREATE PUBLICATION dvdrental FOR ALL TABLES;

2 对源数据库进行备份,采用 pg_dump pg_resotre 来进行(不清楚的同学请百度一下,很简单)

3 在将源数据库恢复到了目的库的 dvdrental 库后

CREATE SUBSCRIPTION publication CONNECTION 'host=192.168.198.200 dbname=dvdrental user=publication password=1234.com port=5432' PUBLICATION dvdrental;

然后我们可以查看当前复制是否被建立。

select * from pg_stat_replication;

看上去还是比较简单的,但上面的操作有以下几个问题

1 我备份的数据是整体备份数据, 还原到目的库,还是仅仅备份表结构然后让主从逻辑去同步数据。

这个问题的两方面看

1 逻辑备份不需要你备份数据库,只要有表结构即可,并且表结构也不要求是一定和原表的表结构一致,只要是不比原表的字段少,类型大致一致即可。

2 那既然逻辑备份可以补足数据,为什么还要进行备份数据的工作,在恢复到目的地,这里有一个问题,就是数据量的问题,如果数据量比较啊,则数据补足的时间会比较慢,所以可以先备份数据过去,在进行复制。

但这里又有一个问题,如果我在备份的时候带有数据,到目的地,在建立复制,是否有数据丢失的情况,因为我在备份恢复的过程中,也有数据写入。

带着这个问题我们做下一个实验

1 我建立一个publication

2 我备份数据库

3 期间我添加数据在publication端

4 我恢复数据库

5 建立subscription查看 在3 好期间的数据是否能补齐

最后的结果是,不能补齐,这和我试想的是一样的,首先我们建立publication 的时候,并没有建立复制槽,而复制槽的建立,是开始数据复制的开始, 所以在复制槽建立前如果在publication端录入的数据,并且在 subscription 端创建订阅时 采用 with (copy_data = false) 那必然是不会有复制槽建立前备份后录入的数据。

但如果我们不实用 copy_data = false 则在同步数据的时候,要不就等待的时间较长,(如果数据量足够大,publication端的 wal_log 的目录会保留很多来不及进行复制的数据操作记录),并且还会有很多重复主键的错误提示,因为复制是从头开始的,通过主键的方式,而备份的数据必然和部分publication的数据重合,但数据是不会丢失的。

这是一点,在做逻辑复制时需要考虑的问题

另一个点是,我在做测试的时候很怪异,我想停止订阅服务,

alter subscription 订阅的名字 disable

提示 订阅不存在

drop subscription 订阅的名字

删除订阅 也提示订阅不存在

无奈之下只能关闭从库,删除publication 和 复制槽

而留下的结果也很有趣,就是连续做了两次 publication subscription 会出现同样名字的subscription的残留,并且尝试删除也失败。

到目前为止,逻辑复制还有一些问题需要搞清楚,在学习的过程中,发现有些怪异的问题并未有明确的文档或者解释,包含英文方面的也目前也未找到特别详细的内容。