流复制和逻辑复制的区别

Difference between Stream Replication and logical replication

谁能告诉我更多关于 PostgreSQL 中物理复制和逻辑复制之间的区别?

TL;DR:逻辑复制发送逐行变化,物理复制发送磁盘块变化。逻辑复制对某些任务更好,物理复制对其他任务更好。

请注意,在 PostgreSQL 12(更新时为当前版本)中,逻辑复制是可靠的 table,但非常有限。如果您问这个问题,请使用物理复制。


流式复制可以逻辑复制。有点复杂。

WAL 运输与流媒体

PostgreSQL中从master向replica发送数据主要有两种方式:

  • WAL-shipping or continuous archiving, where individual write-ahead-log files are copied from pg_xlogarchive_command 运行ning 上的 master 到其他某个位置。 restore_command 在副本的 recovery.conf 运行 中配置副本以获取存档,以便副本可以重放 WAL。

    这是用于时间点复制 (PITR),用作连续备份的方法。

    不需要到主服务器的直接网络连接。复制可能会有很长的延迟,尤其是在没有设置 archive_timeout 的情况下。 WAL 运输不能用于同步复制。

  • 流式复制,其中每个更改都会在发生时通过 TCP/IP 连接直接发送到一个或多个副本服务器。副本必须具有主服务器在其 recovery.confprimary_conninfo 选项中配置的直接网络连接。

    只要副本足够快以跟上,流式复制几乎没有或没有延迟。可用于同步复制。您不能对 PITR1 使用流式复制,因此它对连续备份没有多大用处。如果您将 table 放在主服务器上,哎呀,它也会放在副本上。

因此,这两种方法有不同的目的。

异步流与同步流

除此之外,还有同步异步流复制:

  • 异步流复制中,当主控faster/busier时,允许副本及时落后于主控。如果主服务器崩溃,您可能会丢失尚未复制的数据。

    如果异步副本落后于 master 太远,master 可能会丢弃副本所需的信息,如果 max_wal_size(之前称为 wal_keep_segments) is too low and no slot is used, meaning you have to re-create the replica from scratch. Or the master's pg_wal(was pg_xlog) 如果 max_wal_size 太高或使用了插槽,则可能会填满并停止主机工作,直到磁盘 space 被释放。

  • 同步复制中,主服务器直到副本确认它收到事务后才完成提交2 .如果主服务器崩溃并且您必须故障转移到副本,您永远不会丢失数据。由于副本延迟,主服务器永远不会丢弃副本需要的数据或填满其 xlog 和 运行 磁盘 space。作为交换,如果副本出现问题,它可能会导致主服务器变慢甚至停止工作,并且由于网络延迟,它总是会对主服务器产生一些性能影响。

    当有多个副本时,一次只有一个是同步的。参见 synchronous_standby_names

您不能进行同步日志传送。

您实际上可以将日志传送和异步复制结合起来,以防止在副本落后太多时不得不重新创建副本,而不会冒影响主服务器的风险。这是许多部署的理想配置,结合监控副本落后于主副本的程度以确保它在接受table灾难恢复限制内。

逻辑与物理

之上,我们有 逻辑物理 流复制,如在PostgreSQL 9.4:

  • 物理流复制中,更改几乎在磁盘块级别发送,例如“在关系 12311 的磁盘第 18 页的偏移量 14 处,用十六进制写入元组值 0x2342beef1222....".

    物理复制发送所有内容:PostgreSQL 安装中每个数据库的内容,每个数据库中的所有table。它发送索引条目,当你 VACUUM FULL 时它发送全新的 table 数据,它发送回滚事务的数据等等。所以它会产生很多“噪音”并发送很多多余的数据数据。它还要求副本完全相同,因此您不能执行任何需要事务的操作,例如创建临时文件或未记录的 tables。查询副本会延迟复制,因此需要取消对副本的长时间查询。

作为交换,在副本上应用更改既简单又高效,而且副本与主副本可靠地完全相同。 DDL 是透明复制的,就像其他所有内容一样,因此不需要特殊处理。它还可以在大事务发生时流式传输,因此即使发生大的更改,在主服务器上提交和在副本上提交之间也几乎没有延迟。

物理复制成熟、经过充分测试并被广泛采用。

  • 逻辑流复制,9.4 中的新功能,在更高级别发送更改,并且更有选择性。

它一次只复制一个数据库。它只发送行更改并且只发送已提交的事务,它不必发送真空数据​​、索引更改等。它可以有选择地只发送数据库中某些 table 的数据。这使得逻辑复制 带宽效率更高。

在更高级别上操作也意味着您可以在副本数据库上进行事务处理。您可以创建临时的和未记录的 tables。如果你愿意,甚至是普通的 tables。您可以使用外部数据包装器、视图、创建函数,随心所欲。如果查询 运行 也太长,则无需取消查询。

逻辑复制也可以用于在 PostgreSQL 中构建多主复制,这是使用物理复制无法实现的。

但是,作为交换,它不能(目前)在大交易发生时流式传输。它必须等到他们承诺。因此,在主服务器上提交大事务和应用于副本之间可能会有很长的延迟。

它严格按照提交顺序重放事务,因此小的快速事务可能会滞后于大事务并延迟相当长一段时间。

DDL 不会自动处理。您必须自己保持主副本之间的 table 定义同步,或者使用逻辑复制的应用程序必须有自己的设施来执行此操作。要做到这一点可能很复杂。

应用过程本身也比“在我被告知的地方写一些字节”更复杂。与物理复制相比,它在副本上占用的资源也更多。

当前的逻辑复制实现不成熟或未被广泛采用,或者特别易于使用。

选项太多,告诉我该怎么做

呸。复杂吧?我什至还没有深入了解延迟复制、插槽、max_wal_size、时间线、促销的工作原理、Postgres-XL、BDR 和多主机等的细节

那么你应该做什么

没有唯一的正确答案。否则 PostgreSQL 将只支持一种方式。但是有一些常见的用例:

对于备份和灾难恢复使用pgbarman进行基础备份并为您保留WAL,提供易于管理的连续备份。您仍应定期 pg_dump 备份作为额外保险。

对于具有零数据丢失风险的高可用性,使用流式同步复制。

为了具有低数据丢失风险和更好性能的高可用性,您应该使用异步流复制。为回退启用 WAL 归档或使用复制槽。使用 Icinga 等外部工具监控副本落后于主副本的程度。

参考资料