有没有人能告诉我PostgreSQL中物理复制和逻辑复制的区别?
请注意,在PostgreSQL 12(当前版本)中,逻辑复制已经稳定可靠,但功能相当有限。如果您在询问此问题,请使用物理复制。
流式复制 可能是 逻辑复制。这有点复杂。
在PostgreSQL中,有两种主要的将数据从主服务器发送到副本服务器的方式:
WAL-shipping 或 连续归档(Continuous Archiving),其中单个预写日志文件从pg_xlog
通过在主服务器上运行的archive_command
被复制到另一个位置。 副本的recovery.conf
中配置的restore_command
在副本上运行以获取这些存档,以便副本可以重放WAL。
这就是用作持续备份方法的时间点复制(Point-in-Time Replication)(PITR)所使用的方法。
与主服务器之间不需要直接的网络连接。复制可能会有较长的延迟,特别是没有设置archive_timeout
。WAL-shipping不能用于同步复制。
流式复制(streaming replication),其中每个更改都会在发生时直接通过TCP/IP连接发送到一个或多个副本服务器。 副本必须在其recovery.conf
的primary_conninfo
选项中配置与主服务器的直接网络连接。
只要副本足够快以跟上,流式复制就几乎没有延迟。可以将其用于同步复制(Synchronous Replication)。您不能使用流式复制进行PITR1,因此对于持续备份没有什么用。如果在主服务器上删除表,则副本也会被删除。
因此,这两种方法具有不同的目的。但是,它们都传输物理WAL存档,仅在时间和WAL段是否在途中被存档的方式上有所不同。
通常应该结合使用这两种方法,通常使用流式复制,但启用archive_command
。然后在副本上,设置restore_command
以允许副本在主副之间存在直接连通性问题时从WAL存档中进行还原。
除此之外,还有同步(Synchronous)和异步(Asynchronous)流式复制:
在异步流式复制中,副本允许落后于主服务器的时间,当主服务器更快/更繁忙时。如果主服务器崩溃,则可能会丢失尚未复制的数据。
如果异步副本落后于主服务器太远,当max_wal_size
(先前称为wal_keep_segments
)过低且未使用插槽时,主服务器可能会丢弃副本所需的信息,这意味着您必须从头开始重新创建副本。或者如果 max_wal_size
设置过高或使用了插槽,则主服务器的pg_wal
(先前为pg_xlog
)可能会填满并停止工作,直到释放磁盘空间。synchronous_standby_names
。VACUUM FULL
时,它发送整个新的表数据,它发送回滚的事务的数据等等。因此它产生很多“噪音”并发送大量冗余数据。它还要求副本完全相同,因此您无法执行任何需要事务的操作,例如创建临时或未记录的表。在副本上查询会延迟复制,因此必须取消副本上的长查询。它一次只复制一个数据库。它仅发送已提交的事务的行更改,并且不必发送vacuum数据、索引更改等。它可以选择性地仅向数据库内的某些表发送数据。这使得逻辑复制比物理复制更加节省带宽。
在更高的层面上运行也意味着您可以在副本数据库上执行事务。您可以创建临时表和非记录表。即使是普通表也可以。您可以使用外部数据封装器、视图、创建函数等。如果查询运行时间过长也无需取消。
逻辑复制还可用于在PostgreSQL中构建多主复制,这在物理复制中不可能。
但换取的是,它(目前)无法实时流式传输大型事务,而必须等待它们提交。因此,主服务器上发布大型事务和副本应用它之间可能存在很长的延迟。
它严格按照提交顺序回放事务,因此小型快速事务可能会被大型事务阻塞并延迟很长时间。
DDL不会自动处理。您必须自己在主副本之间保持表定义同步,或者使用逻辑复制应用程序自己的设施来完成此操作。这可能很复杂。
应用过程本身也比“按照指定位置写一些字节”更为复杂。它还需要比物理复制更多的副本资源。
当前的逻辑复制实现并不成熟、普及或特别易于使用。
哇。很复杂吧?我甚至还没涉及延迟复制、插槽、max_wal_size、时间线、如何执行晋升、Postgres-XL、BDR和多主等细节。
那么你应该 做 什么呢?
没有单一正确的答案。否则,PostgreSQL将只支持该方法。但是有一些常见用例:
对于备份和灾难恢复,请使用pgbarman
进行基本备份并保存WAL,提供易于管理的连续备份。您仍应定期进行pg_dump
备份以获得额外的保险。
对于零数据丢失风险的高可用性,请使用流同步复制。
对于低数据丢失风险和更好的性能的高可用性,您应使用异步流复制。要么启用WAL归档以备用,要么使用复制插槽。使用外部工具(如Icinga)监控副本与主服务器之间的延迟。
max_slot_wal_keep_size
选项,用于设置槽位WAL日志的保留限制。考虑到它是高级功能,您可能不需要它。还请注意,wal_keep_segments
已被max_wal_size
设置替换。 - Craig Ringer