流复制和逻辑复制之间的区别

Sim*_* Su 32 database postgresql database-replication

任何人都可以告诉我更多关于PostgreSQL中物理复制和逻辑复制之间的区别吗?

Cra*_*ger 81

TL; DR:逻辑复制发送逐行更改,物理复制发送磁盘块更改.对于某些任务,逻辑复制更好,对于其他任务则是物理复制.

从9.5开始,逻辑复制还不成熟.如果您问这个问题,请使用物理复制.


流复制可以是逻辑复制.这有点复杂.

WAL-shipping vs流媒体

在PostgreSQL中有两种主要方法可以将数据从主数据库发送到副本服务器:

  • WAL-运输连续归档,其中个别预写日志文件从复制pg_xlog通过archive_command在主运行到其他位置.一个restore_command在副本的配置recovery.conf上的副本运行,以获取存档,副本可以重放WAL.

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

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

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

    只要副本足够快以便跟上,流式复制很少或没有延迟.它可以用于同步复制.您不能将流复制用于PITR 1,因此它不能用于连续备份.如果你在主服务器上删除一个表,那么它也会丢弃在副本上.

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

异步与同步流

最重要的是,有同步异步流复制:

  • 异步流复制中,当主设备更快/更忙时,允许副本及时落在主设备之后.如果主服务器崩溃,您可能会丢失尚未复制的数据.

    如果异步副本远远落后于主服务器,则主服务器可能会丢弃副本所需的信息(如果wal_keep_segments太低而且没有使用插槽),这意味着您必须从头开始重新创建副本.或者主机pg_xlog可能会填满并停止主机工作,直到磁盘空间被释放(如果wal_keep_segments太高或使用插槽).

  • 同步复制中,在副本确认已收到事务2之前,主服务器未完成提交.如果主服务器崩溃并且您必须故障转移到副本,则永远不会丢失数据.由于副本延迟,主服务器永远不会丢弃副本所需的数据或填满其xlog并耗尽磁盘空间.作为交换,如果副本有问题,它可能导致主节点减速甚至停止工作,并且由于网络延迟,它总是对主节点产生一些性能影响.

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

您无法进行同步日志传送.

实际上,您可以将日志传送和异步复制相结合,以防止在副本落后太多时重新创建副本,而不会有影响主服务器的风险.这是许多部署的理想配置,同时监控副本在主服务器后面的距离,以确保它在可接受的灾难恢复限制范围内.

逻辑与物理

最重要的是,我们有PostgreSQL 9.4中引入的逻辑物理流复制:

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

    物理复制发送所有内容:PostgreSQL安装中每个数据库的内容,每个数据库中的所有表.它发送索引条目,它发送全新的表数据VACUUM FULL,它为回滚的事务发送数据等.因此它会产生大量的"噪音"并发送大量过多的数据.它还要求副本完全相同,因此您无法执行任何需要事务的操作,例如创建临时表或未记录的表.查询副本会延迟复制,因此需要取消副本上的长查询.

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

    物理复制是成熟的,经过充分测试并被广泛采用.

  • 逻辑流复制(9.4版中的新增功能)在更高级别发送更改,并且更具选择性.

    它一次只复制一个数据库.它仅发送行更改,仅针对已提交的事务,并且不必发送真空数据​​,索引更改等.它可以选择性地仅为数据库中的某些表发送数据.这使得逻辑复制得多的带宽效率.

    在更高级别操作还意味着您可以在副本数据库上执行事务.您可以创建临时和未记录的表.如果你愿意,甚至是普通的桌子.您可以使用外部数据包装器,视图,创建函数,无论您喜欢什么.如果查询运行时间太长,则无需取消查询.

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

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

    它严格按提交顺序重放事务,因此小型快速事务可能会滞后于大事务并被延迟很长一段时间.

    DDL不会自动处理.您必须自己保持主表和副本之间的表定义同步,或者使用逻辑复制的应用程序必须拥有自己的工具才能执行此操作.做到这一点可能很复杂.

    应用过程本身比"写一些字节,我被告知"更复杂.与物理复制相比,它在副本上也需要更多资源.

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

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

唷.复杂,对吧?我甚至没有详细介绍延迟复制,插槽wal_keep_segments,时间表,促销如何运作,Postgres-XL,BDR和多主管等.

那你怎么

没有一个正确的答案.否则PostgreSQL只会支持这种方式.但是有一些常见的用例:

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

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

对于具有低数据丢失风险和更高性能的高可用性,您应该使用异步流复制.要么启用WAL归档以进行回退,要么使用复制槽.使用Icinga等外部工具监控副本在主服务器后面的距离.

参考

  • @Awesome-o 那么复制槽正在使用中,因此 WAL 会无限期保留。然而,在 PostgreSQL 13 中,现在有一个“max_slot_wal_keep_size”选项,用于设置插槽 WAL 保留的限制。将其视为一项高级功能,您可能不需要它。另请注意,“wal_keep_segments”已替换为“max_wal_size”设置。 (4认同)
  • @JoshuaBurns 我正忙于开发,但 https://2ndquadrant.com 上的其他人确实为此类设置提供了帮助。更普遍的是 https://www.postgresql.org/support/professional_support/。 (2认同)
  • 自从这个答案和逻辑复制取得了长足的进步已经有几年了。你的建议有什么变化吗? (2认同)