TL;DR:逻辑复制发送逐行更改,物理复制发送磁盘块更改。逻辑复制对于某些任务更好,而物理复制对于其他任务更好。
请注意,在 PostgreSQL 12(更新时的当前版本)中,逻辑复制稳定可靠,但相当有限。如果您问这个问题,请使用物理复制。
流式复制can be逻辑复制。这一切都有点复杂。
WAL 传送与流式传输
PostgreSQL中从master向replica发送数据主要有两种方式:
-
WAL-航运 or 连续归档,其中各个预写日志文件是从复制的pg_xlog
by the archive_command
在主服务器上运行到其他位置。 Arestore_command
在副本中配置recovery.conf
在副本上运行以获取存档,以便副本可以重播 WAL。
这是用来做的时间点复制(PITR),用作连续备份的方法。
主服务器不需要直接网络连接。复制可能会有很长的延迟,尤其是在没有archive_timeout
放。 WAL 传送不能用于同步复制。
-
流式复制,其中每个更改都会在发生时直接通过 TCP/IP 连接发送到一个或多个副本服务器。副本必须具有主服务器在其配置中配置的直接网络连接recovery.conf
's primary_conninfo
option.
Streaming replication has little or no delay so long as the replica is fast enough to keep up. It can be used for synchronous replication. You cannot use streaming replication for PITR1 so it's not much use for continuous backup. If you drop a table on the master, oops, it's dropped on the replicas too.
因此,这两种方法具有不同的目的。然而,它们都将物理 WAL 档案从主库传输到副本;它们的区别仅在于时间,以及 WAL 段是否会归档到其他地方。
你可以而且通常应该combine这两种方法,通常使用流复制,但使用archive_command
已启用。然后在副本上设置restore_command
如果主数据库和副本数据库之间存在直接连接问题,则允许副本数据库回退以从 WAL 存档进行恢复。
异步流与同步流
除此之外,还有同步 and 异步流式复制:
-
In 异步流式复制当主服务器更快/更忙时,副本可以及时落后于主服务器。如果主服务器崩溃,您可能会丢失尚未复制的数据。
如果异步副本落后主服务器太远,则主服务器可能会丢弃副本所需的信息,如果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
太高或使用了插槽。
-
In synchronous replication the master doesn't finish committing until a replica has confirmed it received the transaction2. You never lose data if the master crashes and you have to fail over to a replica. The master will never throw away data the replica needs or fill up its xlog and run out of disk space because of replica delays. In exchange it can cause the master to slow down or even stop working if replicas have problems, and it always has some performance impact on the master due to network latency.
当有多个副本时,一次只有一个是同步的。看synchronous_standby_names
.
您无法进行同步日志传送。
实际上,您可以将日志传送和异步复制结合起来,以防止在落后太远的情况下重新创建副本,而不会有影响主服务器的风险。对于许多部署来说,这是一个理想的配置,结合监视副本落后于主服务器的距离,以确保其处于可接受的灾难恢复限制内。
逻辑与物理
在之上that我们有logical vs physical流式复制,在 PostgreSQL 9.4 中引入:
-
In 物理流复制更改几乎在磁盘块级别发送,例如“在关系 12311 的磁盘页 18 的偏移量 14 处,写入了十六进制值 0x2342beef1222 的元组......”。
物理复制发送一切:PostgreSQL 安装中每个数据库的内容,每个数据库中的所有表。它发送索引条目,当您发送整个新表数据时VACUUM FULL
,它会发送回滚的事务的数据等。因此它会产生大量的“噪音”并发送大量多余的数据。它还要求副本完全相同,因此您无法执行任何需要事务的操作,例如创建临时表或未记录的表。查询副本会延迟复制,因此需要取消对副本的长时间查询。
作为交换,在副本上应用更改既简单又高效,并且副本可靠地与主服务器完全相同。 DDL 是透明复制的,就像其他一切一样,因此不需要特殊处理。它还可以在发生大事务时对它们进行流式处理,因此即使对于大的更改,主服务器上的提交和副本上的提交之间也几乎没有延迟。
物理复制已经成熟、经过充分测试并被广泛采用。
-
逻辑流式复制9.4 中的新功能,在更高级别发送更改,并且更有选择性。
它一次仅复制一个数据库。它仅发送行更改并且仅发送已提交的事务,并且不必发送真空数据、索引更改等。它可以有选择地仅发送数据库中某些表的数据。这使得逻辑复制much带宽效率更高。
在更高级别上操作还意味着您可以在副本数据库上执行事务。您可以创建临时表和未记录的表。如果你愿意的话,甚至是普通的桌子。您可以使用外部数据包装器、视图、创建函数,无论您喜欢什么。如果查询运行时间太长,也无需取消查询。
逻辑复制还可以用于在 PostgreSQL 中构建多主复制,这是使用物理复制无法实现的。
但作为交换,它(目前)无法在发生大交易时对其进行流式传输。必须等到他们承诺为止。因此,在主服务器上提交大事务和应用于副本服务器之间可能存在很长的延迟。
它严格按照提交顺序重播事务,因此小型快速事务可能会卡在大事务后面并延迟相当长一段时间。
DDL 不会自动处理。您必须自己保持主副本之间的表定义同步,或者使用逻辑复制的应用程序必须拥有自己的工具来执行此操作。要做到这一点可能很复杂。
应用过程本身也比“在我被告知的地方写入一些字节”更复杂。与物理复制相比,它在副本上占用的资源也更多。
当前的逻辑复制实现并不成熟或广泛采用,或者特别易于使用。
选项太多,告诉我该怎么做
唷。很复杂吧?我什至还没有深入了解延迟复制、插槽的细节,max_wal_size
、时间表、促销如何运作、Postgres-XL、BDR 和多主机等。
那么你应该怎么办do?
没有单一的正确答案。否则 PostgreSQL 将只支持这种方式。但有一些常见的用例:
For 备份和灾难恢复 use pgbarman
为您进行基础备份并保留WAL,提供易于管理的连续备份。您仍然应该定期服用pg_dump
备份作为额外保险。
For 高可用性,零数据丢失风险使用流式同步复制。
For 高可用性、低数据丢失风险和更好的性能您应该使用异步流复制。要么启用 WAL 归档以进行回退,要么使用复制槽。使用 Icinga 等外部工具监控副本落后于主服务器的距离。
参考
- 连续归档和 PITR http://www.postgresql.org/docs/current/static/continuous-archiving.html
- 高可用性、负载平衡和复制 http://www.postgresql.org/docs/current/static/high-availability.html
- 复制设置 http://www.postgresql.org/docs/current/static/runtime-config-replication.html
- 恢复配置文件 http://www.postgresql.org/docs/current/static/recovery-config.html
- pgbarman http://www.pgbarman.org/
- repmgr http://www.repmgr.org/
- wiki:复制、集群和连接池 https://wiki.postgresql.org/wiki/Replication,_Clustering,_and_Connection_Pooling