11.3 管理多个备库

本节描述了存在多个备库时,流复制是如何工作的。

11.3.1 同步优先级与同步状态

主库为自己管理的每一个备库指定一个同步优先级(sync_priority同步状态(sync_state 。(上一节并没有提到这一点,即使主库只管理一个备库,也会指定这些值)。

同步优先级(sync_priority) 表示备库在同步模式下的优先级,它是一个固定值。较小的值表示较高的优先级,而0是一个特殊值,表示“异步模式”。备库优先级是一个有序列表,在主库配置参数 synchronous_standby_names中依序给出。例如在以下配置中,standby1standby2的优先级分别为1和2。

synchronous_standby_names = 'standby1, standby2'

(未列于此参数中的备库处于异步模式,优先级为0)

同步状态(sync_state) 是备库的状态,它因所有在列备库的运行状态及其优先级而异,以下是可能的状态:

  • 同步(Sync) 状态的备库,是所有正在工作中的备库中,具有最高优先级的同步备库的状态(异步模式除外)。
  • 潜在(Potential) 状态的备库,是所有工作备库(异步备库除外)中,优先级等于或低于2的闲置同步备库。如果同步备库失效,潜在备库中有着最高优先级的那个将替换为同步备库。
  • 异步(Async) 状态的备库是固定的。主库以与潜在备库相同的方式处理异步备库,只是它们的sync_state永远不会是syncpotential

执行以下查询来显示备库的优先级和状态:

testdb=# SELECT application_name AS host, 
         sync_priority, sync_state FROM pg_stat_replication;
   host   | sync_priority | sync_state
----------+---------------+------------
 standby1 |             1 | sync
 standby2 |             2 | potential
(2 rows)

最近有几个开发者尝试实现“多个同步备库”。详情参见此处

11.3.2 主库如何管理多个备库

主库仅等待来自同步备库的ACK响应。换句话说,主库仅确保同步备库写入并刷新WAL数据。因此在流复制中,只有同步备库的状态是与主库始终一致且同步的。

图11.3展示了潜在备库的ACK响应早于首要备库ACK响应的情况。这时主库并不会完成当前事务的COMMIT操作,而是继续等待首要备库的ACK响应。而当收到首要备库的响应时,后端进程释放锁存器并完成当前事务的处理。

图11.3 管理多个备库图11.3 管理多个备库

备库1与备库2的同步状态分别为syncpotential

  1. 尽管从潜在备库接收到ACK响应,但主库的后端进程会继续等待来自同步备库的ACK响应。
  2. 主库的后端进程释放锁存器,完成当前的事务处理。

在相反的情况下(即首要从库的ACK响应返回早于潜在从库的响应),主库会立即完成当前事务的COMMIT操作,而不会去确认潜在从库是否已经写入和刷盘了WAL数据。

11.3.3 发生故障时的行为

我们再来看看当从库发生故障时主库的表现。

当潜在或异步备库发生故障时,主库会终止连接到故障备库的walsender 进程,并继续进行所有处理。换而言之,主库上的事务处理不会受到这两种备库的影响。

当同步备库发生故障时,主库将终止连接到故障备库的walsender 进程,并使用具有最高优先级的潜在备库替换首要同步备库,如图11.4。与上述的故障相反,主库将会暂停从失效点到成功替换同步备库之间的查询处理。(因此备库的故障检测对于提高复制系统可用性至关重要,故障检测将在下一节介绍)

图11.4 更换同步备库图11.4 更换同步备库

在任何情况下,如果一个或多个备库在同步模式下运行,主库始终只会保留一个同步备库,而同步备库始终与主库保持一致且同步的状态。

下一节:流复制使用两种常见的故障检测过程,不需要任何特别的硬件。