25.1. 不同解决方案的比较

共享磁盘失效切换

共享磁盘失效切换通过仅保存一份数据库副本来避免花在同步上的开销。 这个方案让多台服务器共享使用一个单独的磁盘阵列。 如果主服务器失效,备份服务器将立即挂载该数据库,就像是从一次崩溃中恢复一样。这 个方案允许快速的失效切换并且不会丢失数据。

共享硬件的功能通常由网络存储设备提供,也可以使用完全符合POSIX行为的网络文件系统(NFS)。 这种方案的局限性在于如果共享的磁盘阵列损坏了,那么整个系统将会瘫痪。 另一个局限是备份服务器在主服务器正常运行的时候不能访问共享的存储器。

文件系统复制(块设备)

一种改进的方案是文件系统复制:对文件系统的任何更改都将镜像到备份服务器上。 这个方案的唯一局限是必须确保备份服务器的镜像与主服务器完全一致,特别是写入顺序必须完全相同。 DRBD是Linux上的一种流行的文件系统复制方案。

使用即时恢复(PITR)的热备份

热备份服务器可以通过读取WAL记录流来保持数据库的当前状态。 如果主服务器失效,那么热备份服务器将包含几乎所有主服务器的数据,并可以迅速的将自己切换为主服务器。 这是一个异步方案,并且只能在整个数据库服务器上实施。

使用基于文件的日志传送或流复制,或两者相结合实现PITR备份服务器。前者参阅Section 25.2, 后者参阅Section 25.2.5。请参阅Section 25.5获取关于热备的信息。

基于触发器的主备复制

这个方案将所有修改数据的请求发送到主服务器。主服务器异步向从服务器发送数据的更改信息。 从服务器在主服务器运行的情况下只应答读请求。对于数据仓库的请求来说,从服务器非常理想的。

Slony-I是这个方案的一个例子,它支持针对每个表的粒度并支持多个从服务器。 因为它异步、批量的更新从服务器,在失效切换的时候可能会有数据丢失。

基于语句的复制中间件

以使用一个基于语句的复制中间件程序截取每一个SQL查询,并将其发送到某一个或者全部服务器。 每一个服务器都独立运行。 写请求发送给所有服务器,读请求则仅发送给某一个服务器,从而实现读取的负载均衡。

如果只是简单的广播修改数据的SQL语句, 那么类似random(),CURRENT_TIMESTAMP以及序列函数在不同的服务器上将生成不同的结果。 这是因为每个服务器都独立运行并且广播的是SQL语句而不是如何对行进行修改。 如果这种结果是不可接受的,那么中间件或者应用程序必须保证始终从同一个服务器读取这些值并将其应用到写入请求中。 另外还必须保证每一个事务必须在所有服务器上全部提交成功或者全部回滚, 或者使用两阶段提交(PREPARE TRANSACTIONCOMMIT PREPARED)。 Pgpool-IISequoia是这种方案的实例。

异步多主服务器复制

对于那些不规则连接的服务器(比如笔记本电脑或远程服务器),要在它们之间保持数据一致是很麻烦的。 在这个方案中,每台服务器都独立工作并周期性的与其他服务器通信以识别相互冲突的事务。 可以通过用户或者冲突判决规则处理出现的冲突。

同步多主服务器复制

在这种方案中,每个服务器都可以接受写入请求,修改的数据将在事务被提交之前必须从原始服务器广播到所有其它服务器。 过多的写入动作将导致过多的锁定,从而导致性能低下。 事实上,在多台服务器上同时写的性能总是比在单独一台服务器上写的性能低。 读请求将被均衡的分散到每台单独的服务器。 某些实现使用共享磁盘来减少通信开销。同步多主服务器复制方案最适合于读取远多于写入的场合。 它的优势是每台服务器都能接受写请求因此不需要在主从服务器之间划分工作负荷。因 为在服务器之间发送的是数据的变化,所以不会对非确定性函数(比如random())造成不良影响。

PostgreSQL不提供这种类型的复制。 但是PostgreSQL的两阶段提交(PREPARE TRANSACTIONCOMMIT PREPARED)可以用于在应用层或中间件代码中实现这个功能。

商业解决方案

因为PostgreSQL是开放源代码并且很容易被扩展,许多公司在PostgreSQL的基础上创建了商业的闭源解决方案, 提供独特的失效切换、复制、负载均衡功能。

Table 25-1总结了以上所列的各种解决方案的能力。

Table 25-1. 高可用性,负载均衡,和复制功能矩阵

FeatureSharedDiskFailoverFileSystemReplicationHot/WarmStandbyUsingPITRTrigger-BasedMaster-StandbyReplicationStatement-BasedReplicationM iddlewareAsynchronousMultimasterReplicationSynchronousMultimasterReplication
MostCommonImplementationNASDRBDPITRSlonypgpool-IIBucardo 
CommunicationMethodshareddiskdiskblocksWALtablerowsSQLtablerowstablerowsandrowlocks
Nospecialhardwarerequired 
Allowsmultiplemasterservers    
Nomasterserveroverhead    
Nowaitingformultipleservers   
Masterfailurewillneverlosedata   
Standbyacceptread-onlyqueries  Hotonly
Per-tablegranularity    
Noconflictresolutionnecessary  

有几个解决方案不适合上边这些分类:

数据分区

数据分区将表拆分为数据集。每个数据集只有一台服务器可以修改。例如,数据可以按办事处进行分区,例如,伦敦和巴黎,每个办公室用一个服务器。 如果查询需要伦敦和巴黎相结合的数据,应用程序可以查询两台服务器,或主/备用复制可以用来保持每个服务器上有其他办公室的只读数据副本。

多服务器并行查询执行

许多上述解决方案允许多个服务器来处理多个查询,但不是允许单个查询使用多个服务器来更快完成。 此解决方案允许多个服务器上单个查询同时运行。它通常被通过服务器之间的数据分开而执行其查询的一部分, 并将结果返回到中央服务器,由它来联合结果并返回给用户。Pgpool-II有这种能力。 也可以使用PL/Proxy工具集实现。