26.1. 不同解决方案的比较

  • 共享磁盘故障转移

    • 共享磁盘故障转移通过仅拥有一个数据库副本来避免同步开销。它使用由多个服务器共享的单个磁盘阵列。如果主数据库服务器发生故障,备用服务器就可以挂载并启动数据库,就好像它正在从数据库崩溃中恢复一样。这样可以进行快速故障转移而不会丢失数据。

共享硬件功能在网络存储设备中很常见。尽管必须注意文件系统具有完整的 POSIX 行为,但也可以使用网络文件系统(请参见Section 18.2.2)。此方法的一个重要限制是,如果共享磁盘阵列发生故障或损坏,则主服务器和备用服务器都将无法运行。另一个问题是,在主服务器运行时,备用服务器永远不应访问共享存储。

  • 文件系统(块设备)复制

    • 共享硬件功能的修改版本是文件系统复制,其中对文件系统的所有更改都将镜像到另一台计算机上的文件系统。唯一的限制是必须以确保备用服务器具有文件系统的一致副本的方式进行镜像-特别是,写入备用数据库的 Sequences 必须与主服务器上的 Sequences 相同。 DRBD 是针对 Linux 的流行文件系统复制解决方案。
  • 预写日志传送

    • 通过读取预写日志(WAL)记录流,可以使热备用服务器和热备用服务器保持最新状态。如果主服务器发生故障,则备用数据库将包含主服务器的几乎所有数据,并且可以迅速成为新的主数据库服务器。这可以是同步的或异步的,并且只能在整个数据库服务器上完成。

备用服务器可以使用基于文件的日志传送(Section 26.2)或流复制(请参见Section 26.2.5)或两者的组合来实现。有关热待机的信息,请参见Section 26.5

  • Logical Replication

    • 逻辑复制允许数据库服务器将数据修改流发送到另一台服务器。 PostgreSQL 逻辑复制从 WAL 构造逻辑数据修改流。逻辑复制允许复制单个表中的数据更改。逻辑复制不需要将特定的服务器指定为主服务器或副本服务器,而是允许数据沿多个方向流动。有关逻辑复制的更多信息,请参见Chapter 31。通过逻辑解码接口(Chapter 49),第三方扩展也可以提供类似的功能。
  • 基于触发器的主备复制

    • 主备复制设置会将所有数据修改查询发送到主服务器。主服务器异步将数据更改发送到备用服务器。主服务器运行时,备用数据库可以回答只读查询。备用服务器是数据仓库查询的理想选择。

Slony-I 是这种复制类型的示例,具有每个表的粒度,并且支持多个备用服务器。因为它异步(批量)更新备用服务器,所以在故障转移期间可能会丢失数据。

  • 基于语句的复制中间件

    • 使用基于语句的复制中间件,程序将拦截每个 SQL 查询,并将其发送到一个或所有服务器。每个服务器独立运行。必须将读写查询发送到所有服务器,以便每个服务器都可以接收任何更改。但是只读查询只能发送到一台服务器,从而可以在其中分配读取的工作负载。

如果只是简单地 Broadcast 查询而未修改,则类似random()CURRENT_TIMESTAMP和序列的函数在不同服务器上可以具有不同的值。这是因为每个服务器都独立运行,并且因为 SQL 查询是 Broadcast 的(而不是实际修改的行)。如果这是不可接受的,则中间件或应用程序必须从单个服务器查询这些值,然后在写查询中使用这些值。另一种选择是将该复制选项与传统的主备设置一起使用,即数据修改查询仅发送到主服务器,并通过主备复制而不是复制中间件传播到备用服务器。还必须注意,所有事务都可能在所有服务器上提交或中止,也许使用两阶段提交(PREPARE TRANSACTIONCOMMIT PREPARED)。 Pgpool-II 和连续钨是这种复制的示例。

  • 异步多主复制

    • 对于不定期连接或通信链接速度较慢的服务器(例如笔记本电脑或远程服务器),保持服务器之间的数据一致性是一个挑战。使用异步多主复制,每个服务器独立工作,并定期与其他服务器通信以标识冲突的事务。可以通过用户或冲突解决规则解决冲突。 Bucardo 是这种复制的一个示例。
  • 同步多主复制

    • 在同步多主复制中,每个服务器都可以接受写请求,并且在每个事务提交之前,已修改的数据将从原始服务器传输到每个其他服务器。繁重的写入活动可能导致过多的锁定和提交延迟,从而导致性能下降。读取请求可以发送到任何服务器。一些实现使用共享磁盘来减少通信开销。同步多主复制最适合大多数读取工作负载,尽管它的主要优点是任何服务器都可以接受写请求-无需在主服务器和备用服务器之间划分工作负载,并且因为数据更改是从一台服务器发送到另一台服务器的,像random()这样的不确定函数没有问题。

PostgreSQL 不提供这种复制,尽管可以使用 PostgreSQL 两阶段提交(PREPARE TRANSACTIONCOMMIT PREPARED)在应用程序代码或中间件中实现该复制。

  • Commercial Solutions

    • 由于 PostgreSQL 是开源的并且易于扩展,因此许多公司采用 PostgreSQL 并创建了具有独特的故障转移,复制和负载平衡功能的商业性开源解决方案。

Table 26.1总结了上面列出的各种解决方案的功能。

表 26.1 高可用性,负载平衡和复制功能矩阵

Feature共享磁盘故障转移文件系统复制预写日志传送Logical Replication基于触发器的主备复制基于语句的复制中间件异步多主复制同步多主复制
最常见的实现NASDRBD内置流复制内置逻辑复制,pgologicLondiste, Slonypgpool-IIBucardo
Communication methodshared diskdisk blocksWALlogical decodingtable rowsSQLtable rows表行和行锁
无需特殊硬件
允许多个主服务器
无主服务器开销
无需 await 多台服务器 关闭同步关闭同步
主站故障将永远不会丢失数据启用同步启用同步
副本接受只读查询 热备用
Per-table granularity
无需解决冲突

有些解决方案不属于上述类别:

  • Data Partitioning

    • 数据分区将表拆分为数据集。每个集只能由一台服务器修改。例如,数据可以由办公室(例如伦敦和巴黎)分区,每个办公室中都有一台服务器。如果需要结合伦敦和巴黎数据进行查询,则应用程序可以查询两个服务器,或者可以使用主/备用复制在每个服务器上保留其他办公室数据的只读副本。
  • 多服务器并行查询执行

    • 上述许多解决方案都允许多个服务器处理多个查询,但是没有一个允许单个查询使用多个服务器来更快地完成。该解决方案允许多个服务器在单个查询上同时工作。通常可以通过在服务器之间拆分数据并让每个服务器执行其查询的一部分并将结果返回到中央服务器,然后在中央服务器中将它们组合并返回给用户来实现。 Pgpool-II 具有此功能。另外,这可以使用 PL/Proxy 工具集来实现。