# 高可用与复制

URL: https://caijiao.org/postgresql/project/advanced-features/replication
Source: docs/postgresql/project/advanced-features/replication.md
Description: 本章节介绍 PostgreSQL 中的高可用性与数据复制机制，包括主从复制、同步与异步复制等技术。

在 PostgreSQL 中，高可用性和数据复制是确保数据库系统稳定运行和提高系统可靠性的关键技术。复制技术不仅可以提高数据库的可用性，还能实现负载均衡、灾难恢复和数据冗余。

## 1. 高可用性概述

高可用性（High Availability，HA）指的是系统在长期运行过程中，保持业务连续性、减少停机时间和故障恢复的能力。对于数据库系统来说，高可用性是确保业务服务不间断的关键组成部分。

PostgreSQL 提供了多种实现高可用性的方式，包括：

- **主从复制**：数据从主节点复制到多个从节点。
- **同步复制**：确保主节点与从节点的数据一致性。
- **自动故障转移**：在主节点出现故障时，自动将从节点提升为新的主节点。

## 2. 数据复制概述

数据复制是将一个数据库中的数据复制到另一个数据库中，以实现数据冗余、负载均衡和故障恢复。PostgreSQL 支持多种复制方式：

- **流复制**（Streaming Replication）：一种基于 WAL（Write-Ahead Logging）机制的实时复制方式。
- **逻辑复制**（Logical Replication）：通过发布/订阅机制将数据复制到其他数据库。
- **同步复制**与**异步复制**：控制复制的实时性与一致性。

## 3. 主从复制

主从复制是 PostgreSQL 高可用性架构的基础。主节点处理所有的读写请求，而从节点则复制主节点的数据并提供只读查询。流复制是实现主从复制的主要方式。

### 配置主节点（Primary）

在主节点上启用流复制，首先需要设置 `wal_level` 为 `replica`，并配置相关参数以允许从节点连接。

```sql
-- 修改 PostgreSQL 配置文件 postgresql.conf
wal_level = replica
max_wal_senders = 5
wal_keep_size = 16MB

-- 修改 pg_hba.conf 文件，允许从节点的连接
host    replication     replicator    192.168.1.0/24        md5
````

此外，需要创建一个用于复制的专用用户 `replicator`。

```sql
-- 创建复制专用用户
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicator_password';
```

### 配置从节点（Standby）

从节点需要连接到主节点并获取数据流。在从节点上设置 `standby.signal` 文件，并配置主节点信息。

```bash
# 在从节点的数据目录中创建 standby.signal 文件
touch /var/lib/postgresql/data/standby.signal
```

编辑 `postgresql.conf`，配置主节点连接信息。

```sql
# 配置从节点连接到主节点
primary_conninfo = 'host=primary_host port=5432 user=replicator password=replicator_password'
```

重新启动从节点，使其开始同步数据。

```bash
# 启动从节点
pg_ctl restart -D /var/lib/postgresql/data
```

## 4. 同步与异步复制

在流复制中，复制方式可以是同步或异步。它们之间的主要区别是数据一致性的保障程度。

### 异步复制

在异步复制模式下，主节点会在提交事务后立即响应客户端，而不等待从节点确认数据已同步。这种模式下，主节点和从节点之间可能存在延迟，且主节点出现故障时，可能会丢失未同步的数据。

```sql
# 异步复制示例配置
synchronous_commit = off
```

### 同步复制

同步复制则要求主节点在提交事务之前，等待至少一个从节点确认数据已经同步。这种模式确保了主节点和从节点数据的一致性，但可能会导致主节点的响应时间增加。

```sql
# 配置同步复制
synchronous_standby_names = 'ANY 1 (standby_1, standby_2)'
synchronous_commit = on
```

## 5. 自动故障转移与高可用性集群

自动故障转移（Automatic Failover）是实现 PostgreSQL 高可用性的一个重要部分。在主节点出现故障时，从节点会自动被提升为新的主节点，确保系统的连续运行。

### 使用 `pg_auto_failover`

`pg_auto_failover` 是 PostgreSQL 提供的一个高可用性解决方案，它能够自动检测主节点的故障并自动切换到从节点。通过此工具，可以实现无需人工干预的故障恢复。

### 使用 `Patroni` 集群管理

`Patroni` 是一个开源的高可用性管理工具，可以用来管理 PostgreSQL 集群。它基于 Etcd 或 Consul 进行主节点选举，提供自动故障转移功能。

```bash
# Patroni 安装与配置示例
# 配置 Etcd 或 Consul 作为分布式存储
# 配置 PostgreSQL 集群节点
```

## 6. 逻辑复制

逻辑复制允许在不同 PostgreSQL 数据库之间选择性地复制数据。通过逻辑复制，您可以将一部分表的数据从一个数据库复制到另一个数据库。

### 配置逻辑复制

1. 在主节点上创建发布（publication）。

```sql
-- 创建一个发布，用于逻辑复制
CREATE PUBLICATION my_publication FOR TABLE my_table;
```

2. 在从节点上创建订阅（subscription）。

```sql
-- 创建一个订阅，将主节点的数据复制到从节点
CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=primary_host port=5432 user=replicator password=replicator_password dbname=postgres'
PUBLICATION my_publication;
```

## 7. 小结

PostgreSQL 提供了强大的高可用性和复制功能，通过流复制、同步复制、异步复制以及逻辑复制等技术，可以帮助您实现数据冗余、负载均衡和快速故障恢复。选择合适的复制方式和工具将大大提高数据库系统的可靠性和扩展性。通过自动故障转移和集群管理工具（如 `pg_auto_failover` 和 `Patroni`），您可以实现高度自动化的高可用性 PostgreSQL 集群。
