Postgresql 中文操作指南
27.1. Comparison of Different Solutions #
-
Shared Disk Failover
-
共享磁盘故障转移通过仅保留数据库的一个副本来避免同步开销。它使用一个单一的磁盘阵列,由多个服务器共享。如果主数据库服务器发生故障,备用服务器将能够挂载并启动数据库,就好像它正在从数据库崩溃中恢复一样。这允许快速故障转移而不会丢失数据。
-
网络存储设备中常见共享硬件功能。也可以使用网络文件系统,尽管必须注意文件系统具有完整的 POSIX 行为(参见 Section 19.2.2.1)。此方法的一个重大限制是,如果共享磁盘阵列发生故障或损坏,主服务器和备用服务器将均无法运行。另一个问题是,在主服务器运行时,备用服务器切勿访问共享存储。
-
-
文件系统(块设备)复制
-
共享硬件功能的修改版本是文件系统复制,其中对文件系统的所有更改都镜像到驻留在另一台计算机上的文件系统中。唯一的限制是,必须以确保备用服务器具有文件系统的一致副本的方式进行镜像——具体来说,对备用服务器的写入必须按主服务器上写入的顺序进行。DRBD 是 Linux 的一种流行文件系统复制解决方案。
-
-
Write-Ahead Log Shipping
-
可以通过读取预写日志 (WAL) 记录流来保持热备和热备服务器的最新状态。如果主服务器发生故障,备用服务器将包含主服务器的几乎所有数据,并且可以快速成为新的主数据库服务器。这可以是同步的或异步的,并且只能针对整个数据库服务器执行。
-
可以使用基于文件的日志传送( Section 27.2)或流复制(参见 Section 27.2.5)来实现备用服务器,也可以同时使用这两种方法的组合。有关热备用的信息,请参见 Section 27.4。
-
-
Logical Replication
-
逻辑复制允许数据库服务器将数据修改流发送到其他服务器。PostgreSQL 逻辑复制从 WAL 构建逻辑数据修改流。逻辑复制允许按表为基础复制数据更改。此外,发布其自身更改的服务器也可以订阅来自其他服务器的更改,从而允许数据向多个方向流动。有关逻辑复制的更多信息,请参见 Chapter 31。通过逻辑解码接口( Chapter 49),第三方扩展还可以提供类似的功能。
-
-
Trigger-Based Primary-Standby Replication
-
基于触发的复制设置通常将数据修改查询引导到指定的主服务器。基于每张表操作,主服务器通常异步地向备用服务器发送数据更改。备用服务器可以在主服务器运行时回答查询,并可能允许进行一些本地数据更改或写入活动。这种形式的复制通常用于卸载大型分析或数据仓库查询。
-
Slony-I 就是这种类型的复制的示例,具有基于每张表的粒度,并支持多个备用服务器。因为它异步更新备用服务器(批量),因此故障转移期间可能会丢失数据。
-
-
SQL-Based Replication Middleware
-
使用基于 SQL 的复制中间件,一个程序会拦截每个 SQL 查询并将其发送到一个或所有服务器。每个服务器独立操作。读写查询必须发送到所有服务器,以便每个服务器都能接收到任何更改。但在只读查询可以发送到一个服务器,从而可以在服务器之间分布读取工作负载。
-
如果查询只是未经修改地广播,那么诸如 random() 、 CURRENT_TIMESTAMP 和序列等函数在不同的服务器上可以有不同的值。这是因为每个服务器独立运行,并且因为广播的是 SQL 查询而不是实际的数据更改。如果这是不可接受的,那么中间件或应用程序必须从单个数据源确定此类值,然后在写入查询中使用这些值。还需要注意的是,所有事务在所有服务器上都必须提交或中止,可能使用两阶段提交 ( PREPARE TRANSACTION 和 COMMIT PREPARED )。Pgpool-II 和 Continuent Tungsten 是这类复制的示例。
-
-
Asynchronous Multimaster Replication
-
对于不定期连接或通信链路较慢的服务器(如笔记本电脑或远程服务器),要在服务器之间保持数据一致性是一项挑战。使用异步多主复制,每个服务器独立工作,并定期与其他服务器通信以识别冲突的事务。这些冲突可以通过用户或冲突解决规则来解决。Bucardo 就是这种类型的复制示例。
-
-
Synchronous Multimaster Replication
-
在同步多主复制中,每个服务器都可以接受写入请求,并且在每个事务提交之前,已修改的数据会从原始服务器传输到其他每个服务器。繁重的写入活动可能导致过度锁定和提交延迟,从而导致性能低下。可以将读取请求发送到任何服务器。某些实现使用共享磁盘来减少通信开销。同步多主复制最适合大多数读取工作负载,尽管它的最大优势在于任何服务器都可以接受写入请求——无需在主服务器和备用服务器之间划分工作负载,并且由于数据更改是从一台服务器发送到另一台服务器,因此不存在 random() 等非确定性函数的问题。
-
PostgreSQL 不提供此类型的复制,不过 PostgreSQL 的两阶段提交 ( PREPARE TRANSACTION 和 COMMIT PREPARED ) 可用于在应用程序代码或中间件中实现此复制。
-
Table 27.1总结了上述各种解决方案的功能。
Table 27.1. High Availability, Load Balancing, and Replication Feature Matrix
Feature |
Shared Disk |
File System Repl. |
Write-Ahead Log Shipping |
Logical Repl. |
Trigger-Based Repl. |
SQL Repl. Middle-ware |
Async. MM Repl. |
Sync. MM Repl. |
Popular examples |
NAS |
DRBD |
built-in streaming repl. |
built-in logical repl., pglogical |
Londiste, Slony |
pgpool-II |
Bucardo |
|
Comm. method |
shared disk |
disk blocks |
WAL |
logical decoding |
table rows |
SQL |
table rows |
表格行和行锁 |
No special hardware required |
• |
• |
• |
• |
• |
• |
• |
|
Allows multiple primary servers |
• |
• |
• |
• |
||||
No overhead on primary |
• |
• |
• |
• |
||||
无需等待多台服务器 |
• |
with sync off |
with sync off |
• |
• |
|||
主服务器故障永远不会丢失数据 |
• |
• |
with sync on |
with sync on |
• |
• |
||
Replicas accept read-only queries |
with hot standby |
• |
• |
• |
• |
• |
||
Per-table granularity |
• |
• |
• |
• |
||||
No conflict resolution necessary |
• |
• |
• |
• |
• |
• |
有几种解决方案不属于上述类别:
-
Data Partitioning
-
数据分区将表拆分为数据集。每个数据集只能由一台服务器修改。例如,数据可以按办事处分区,例如伦敦和巴黎,每个办事处有一台服务器。如果需要查询合并伦敦和巴黎的数据,应用程序可以查询两台服务器,或使用主备复制在每个服务器上保留另一个办事处数据的只读副本。
-
-
Multiple-Server Parallel Query Execution
-
上述许多解决方案允许多台服务器处理多个查询,但没有一种解决方案允许单个查询使用多台服务器来更快地完成。此解决方案允许多台服务器同时在一个查询上工作。通常是通过将数据拆分到服务器之间,并让每台服务器执行其查询部分并将结果返回到中央服务器(在其中合并结果并将其返回给用户)来实现的。这可以使用 PL/Proxy 工具集来实现。
-
还应注意,由于 PostgreSQL 是开源且易于扩展的,许多公司已经采用了 PostgreSQL 并创建了具有独特故障转移、复制和负载平衡功能的商业闭源解决方案。本文不讨论这些内容。