## 27.1.不同解决方案的比较 共享磁盘故障切换 共享磁盘故障切换通过只拥有一个数据库副本来避免同步开销。它使用由多台服务器共享的单个磁盘阵列。如果主数据库服务器出现故障,备用服务器可以装载和启动数据库,就像它正在从数据库崩溃中恢复一样。这允许在不丢失数据的情况下进行快速故障切换。 共享硬件功能在网络存储设备中很常见。也可以使用网络文件系统,但必须注意文件系统具有完整的POSIX行为(请参阅[第19.2.2.1节](creating-cluster.html#CREATING-CLUSTER-NFS))。此方法的一个重要限制是,如果共享磁盘阵列出现故障或损坏,则主服务器和备用服务器都无法正常工作。另一个问题是,在主服务器运行时,备用服务器不应访问共享存储。 文件系统(块设备)复制 共享硬件功能的一个改进版本是文件系统复制,其中对文件系统的所有更改都会镜像到另一台计算机上的文件系统。唯一的限制是,镜像必须以确保备用服务器具有文件系统的一致副本的方式进行,具体来说,必须按照与主服务器相同的顺序写入备用服务器。DRBD是一种流行的Linux文件系统复制解决方案。 提前写日志传送 通过读取预写日志(WAL)记录流,热备和热备服务器可以保持最新状态。如果主服务器出现故障,备用服务器将包含主服务器的几乎所有数据,并且可以快速成为新的主数据库服务器。这可以是同步的,也可以是异步的,并且只能对整个数据库服务器执行。 备用服务器可以使用基于文件的日志传送来实现([第27.2节](warm-standby.html))或流式复制(请参阅[第27.2.5节](warm-standby.html#STREAMING-REPLICATION)),或两者兼而有之。有关热备用的信息,请参阅[第27.4节](hot-standby.html). 逻辑复制 逻辑复制允许数据库服务器向另一台服务器发送数据修改流。PostgreSQL逻辑复制从WAL构建逻辑数据修改流。逻辑复制允许在每个表的基础上复制数据更改。此外,发布自己更改的服务器也可以订阅来自另一台服务器的更改,从而允许数据向多个方向流动。有关逻辑复制的更多信息,请参阅[第31章](logical-replication.html).通过逻辑解码接口([第49章](logicaldecoding.html)),第三方扩展也可以提供类似的功能。 基于触发器的主备用复制 基于触发器的复制设置通常会将数据修改查询传送到指定的主服务器。主服务器基于每个表进行操作,将数据更改(通常)异步发送到备用服务器。备用服务器可以在主服务器运行时回答查询,并允许一些本地数据更改或写入活动。这种形式的复制通常用于卸载大型分析或数据仓库查询。 Slony-I就是这类复制的一个例子,它具有每表粒度,并且支持多个备用服务器。由于它异步(成批)更新备用服务器,因此在故障转移期间可能会丢失数据。 基于SQL的复制中间件 使用基于SQL的复制中间件,程序会截获每个SQL查询,并将其发送到一台或所有服务器。每台服务器都独立运行。读写查询必须发送到所有服务器,以便每个服务器都接收任何更改。但只读查询只能发送到一台服务器,这样就可以在它们之间分配读取工作负载。 如果查询只是未经修改的广播,那么`随机的`, `当前时间戳`,序列在不同的服务器上可以有不同的值。这是因为每台服务器都独立运行,而且SQL查询是广播的,而不是实际的数据更改。如果这是不可接受的,则中间件或应用程序必须从单个源确定这些值,然后在写查询中使用这些值。还必须注意,所有服务器上的所有事务要么提交,要么中止,可能使用两阶段提交([准备交易](sql-prepare-transaction.html)和[做好准备](sql-commit-prepared.html)).Pgpool II和Continuent Woods就是这种复制的例子。 异步多主机复制 对于没有定期连接或通信链路较慢的服务器,如笔记本电脑或远程服务器,保持服务器之间的数据一致性是一项挑战。使用异步多主机复制,每台服务器独立工作,并定期与其他服务器通信,以识别冲突事务。冲突可以由用户或冲突解决规则解决。Bucardo就是这种复制的一个例子。 同步多主机复制 在同步多主机复制中,每台服务器都可以接受写请求,在提交每个事务之前,修改后的数据会从原始服务器传输到其他每台服务器。大量写入活动可能会导致过度锁定和提交延迟,从而导致性能低下。读取请求可以发送到任何服务器。有些实现使用共享磁盘来减少通信开销。同步多主机复制最适合于大部分读取工作负载,尽管它的最大优势是任何服务器都可以接受写请求——不需要在主服务器和备用服务器之间划分工作负载,而且由于数据更改是从一台服务器发送到另一台服务器的,因此不存在诸如`随机的`. PostgreSQL不提供这种类型的复制,尽管PostgreSQL需要两阶段提交([准备交易](sql-prepare-transaction.html)和[做好准备](sql-commit-prepared.html))可用于在应用程序代码或中间件中实现这一点。 [表27.1](different-replication-solutions.html#HIGH-AVAILABILITY-MATRIX)总结了上述各种解决方案的功能。 **表27.1.高可用性、负载平衡和复制功能矩阵** | 特色 | 共享磁盘 | 文件系统Repl。 | 提前写日志传送 | 逻辑回复。 | 扳机-​基于Repl。 | SQL Repl。中间件 | 异步。嗯,回复。 | 同步。嗯,回复。 | | --- | ---- | --------- | ------- | ----- | ----------- | ------------ | -------- | -------- | | 流行的例子 | NAS | DRBD | 内置流媒体复制。 | 内置逻辑应答器。,pglogical | 孤独,斯隆 | pgpool II | 布卡多 | | | 通信方法 | 共享磁盘 | 磁盘块 | 沃尔 | 逻辑解码 | 表行 | SQL | 表行 | 表行和行锁 | | 不需要特殊的硬件 | | • | • | • | • | • | • | • | | 允许多个主服务器 | | | | • | | • | • | • | | 主系统无开销 | • | | • | • | | • | | | | 无需等待多台服务器 | • | | 在同步关闭的情况下 | 在同步关闭的情况下 | • | | • | | | 主故障永远不会丢失数据 | • | • | 同步打开时 | 同步打开时 | | • | | • | | 副本接受只读查询 | | | 热备用 | • | • | • | • | • | | 每表粒度 | | | | • | • | | • | • | | 没有必要解决冲突 | • | • | • | | • | • | | • | 有几种解决方案不符合上述类别: 数据分区 数据分区将表拆分为数据集。每个集合只能由一台服务器修改。例如,数据可以按办公室进行分区,例如伦敦和巴黎,每个办公室都有一台服务器。如果需要结合伦敦和巴黎数据进行查询,应用程序可以同时查询这两台服务器,或者可以使用主/备用复制在每台服务器上保留另一个办公室数据的只读副本。 多服务器并行查询执行 上述许多解决方案都允许多台服务器处理多个查询,但都不允许单个查询使用多台服务器更快地完成。此解决方案允许多台服务器同时处理单个查询。它通常是通过在服务器之间拆分数据,让每台服务器执行其查询部分,并将结果返回到一个中央服务器,在那里它们被合并并返回给用户来实现的。这可以使用PL/Proxy工具集实现。 还应注意的是,由于PostgreSQL是开放源代码且易于扩展的,许多公司已经采用了PostgreSQL,并创建了具有独特故障切换、复制和负载平衡功能的商业封闭源代码解决方案。这里不讨论这些问题。