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

mxg2im7a  于 2022-12-03  发布在  PostgreSQL
关注(0)|答案(1)|浏览(182)

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

wsewodh2

wsewodh21#

  • TL;DR*:逻辑复制发送逐行更改,物理复制发送磁盘块更改。逻辑复制更适合某些任务,物理复制更适合其他任务。

请注意,在PostgreSQL 12(更新时为最新版本)中,逻辑复制是稳定可靠的,但相当有限。如果您要问这个问题,请使用物理复制。
流复制可以是逻辑复制,这有点复杂。

WAL-shipping与流媒体

在PostgreSQL中,从主服务器向副本服务器发送数据主要有两种方式:

  • WAL-shipping 或 * 连续归档 *,其中主服务器上运行的archive_command会将单独的预写日志文件从pg_xlog复制到其他位置。在副本服务器的recovery.conf中配置的restore_command会在副本服务器上运行,以获取归档,以便副本服务器可以重放WAL。

这是用于 * 时间点复制 *(PITR)的内容,PITR是一种连续备份方法。
主服务器不需要直接网络连接。复制可能会有很长的延迟,尤其是在没有archive_timeout集的情况下。WAL传送不能用于同步复制。

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

只要副本的速度足够快,流式复制几乎没有延迟。它可用于 * 同步复制 *。您不能对PITR 1使用流式复制,因此它对连续备份没有太大用处。如果您删除主服务器上的表,哎呀,副本上的表也会被删除。
然而,这两种方法都是将物理WAL档案从主服务器传输到副本服务器;它们的区别仅在于时间安排以及WAL段是否沿着的其他地方存档。
您可以而且通常应该 * 合并 * 这两种方法,通常使用流式复制,但要启用archive_command。然后在副本上设置restore_command,以便在主服务器和副本服务器之间存在直接连接问题时,允许副本服务器回退到从WAL归档恢复。

异步流与同步流

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

  • 在 * 异步流式复制 * 中,当主服务器更快/更忙时,允许副本服务器在时间上落后于主服务器。如果主服务器崩溃,您可能会丢失尚未复制的数据。

如果异步副本远远福尔斯于主服务器,则主服务器可能会丢弃副本所需的信息,如果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太高或使用了插槽,主服务器可能会停止工作,直到磁盘空间被释放。

  • 在 * 同步复制 * 中,主服务器在副本服务器确认收到事务后才完成提交2。如果主服务器崩溃,您将不得不故障转移到副本服务器,您永远不会丢失数据。主服务器永远不会丢弃副本服务器所需的数据,也不会因为副本服务器延迟而填满其xlog并耗尽磁盘空间。作为交换,如果副本出现问题,它可能会导致主服务器速度减慢甚至停止工作,而且由于网络延迟,它总是会对主服务器的性能产生一些影响。

当有多个复本时,一次只有一个复本是同步的。请参阅synchronous_standby_names
不能使用同步日志传送。
实际上,您可以将日志传送和异步复制结合起来,以避免在副本福尔斯太多的情况下必须重新创建副本,而不会有影响主服务器的风险。对于许多部署来说,这是一种理想的配置,它与监视副本落后于主服务器的程度相结合,以确保副本处于可接受的灾难恢复限制之内。

逻辑与物理

除此之外,我们还拥有PostgreSQL 9.4中引入的逻辑流复制和物理流复制:

  • 在 * 物理流复制 * 中,几乎在磁盘块级别发送改变,如“在关系12311的磁盘页18的偏移14处,写入十六进制值为0x 2342 beef 1222的元组......"。

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

在交换中,在副本上应用更改是简单而高效的,并且副本与主副本完全相同。DDL是透明复制的,就像其他任何东西一样,因此不需要特殊处理。它还可以在大型事务发生时进行流处理,因此即使是大型更改,在主副本上的提交和在副本上的提交之间也几乎没有延迟。
物理复制已成熟,经过充分测试并得到广泛采用.

    • 逻辑流复制 * 是9.4中的新增功能,它可以在更高级别发送更改,而且选择性更强。

它一次只复制一个数据库。它只发送行更改和已提交的事务,并且它不必发送真空数据、索引更改等。它可以选择性地只发送数据库中某些表的数据。这使得逻辑复制 * 大大 * 提高了带宽效率。
在更高级别上操作还意味着您可以在副本数据库上执行事务。您可以创建临时表和未记录的表。如果需要,甚至可以创建普通表。您可以使用外部数据 Package 、视图、创建函数等任何您喜欢的功能。如果查询运行时间过长,也不需要取消查询。
逻辑复制也可用于在PostgreSQL中构建多主复制,这是使用物理复制无法实现的。
但是,作为交换,它(目前)不能在大事务发生时进行流传输,它必须等到事务提交,因此在主服务器上提交大事务和应用到副本服务器之间可能会有很长的延迟。
它严格按照提交顺序重放事务,因此小的快速事务可能会卡在大事务后面,并延迟很长时间。
DDL不是自动处理的。您必须自己在主服务器和副本服务器之间保持表定义同步,或者使用逻辑复制的应用程序必须有自己的工具来实现这一点。要做到这一点可能会很复杂。
应用过程本身也比“在要求的位置写入一些字节”复杂得多,而且它在副本上占用的资源也比物理复制多。
当前的逻辑复制实现并不成熟,也没有被广泛采用,或者特别容易使用。

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

很复杂吧?我还没有深入到延迟复制、插槽、max_wal_size、时间线、升级如何工作、Postgres-XL、BDR和多主控等细节。
那么你应该怎么做呢?
没有唯一的正确答案。否则PostgreSQL只会支持这一种方式。但有几个常见的用例:
对于 * 备份和灾难恢复 *,请使用pgbarman进行基本备份并为您保留WAL,从而提供易于管理的连续备份。您仍应定期进行pg_dump备份以确保安全。
要实现 * 高可用性和零数据丢失风险 *,请使用流式同步复制。
若要 * 具有低数据遗失风险和较佳效能的高可用性 *,您应该使用异步串流复写。请启用WAL封存以进行后援,或使用复写插槽。请使用Icinga之类的外部工具,监视复本落后于主服务器的程度。

参考

相关问题