PostgreSQL 高可用性同步复制的设置

学习如何配置使用同步流复制实现零数据丢失(RPO=0)的 PostgreSQL 高可用性。本分步教程涵盖了 `wal_level`、复制槽、`pg_basebackup` 的关键配置,以及如何在主服务器和备用服务器上正确设置 `synchronous_commit` 参数,从而保证关键环境下的事务持久性。

38 浏览量

在 PostgreSQL 中配置同步复制实现高可用性

为 PostgreSQL 配置高可用性 (HA) 对任何关键业务应用程序都至关重要。虽然异步复制提供了性能优势,但如果主服务器在更改完全传输到备用服务器之前发生故障,它本身就存在数据丢失的风险。同步流复制解决了这个问题,它保证事务只有在数据成功写入主服务器和至少一个指定备用服务器的 WAL(预写日志)之后才被视为提交。这确保了恢复点目标 (RPO) 为零。

本综合指南将引导您完成建立一个健壮、零数据丢失的 PostgreSQL 复制设置所需的基本配置步骤。我们将重点关注支撑这种高可用性架构的关键参数,例如 wal_levelsynchronous_commit

先决条件

在开始之前,请确保您已设置两台 PostgreSQL 服务器(主服务器和备用服务器),并运行相同的主版本 PostgreSQL。两台服务器都必须具有网络连接。本指南假设:

  • 主服务器主机名/IPpg_primary
  • 备用服务器主机名/IPpg_standby
  • 复制用户repl_user(已创建并具有适当权限)
  • 数据库名称mydb

步骤 1:配置主服务器

主服务器需要特定的设置来启用流复制并管理同步提交所需的预写日志 (WAL)。

A. 调整主服务器上的 postgresql.conf

编辑主服务器的 postgresql.conf 文件。以下参数是流复制的强制性参数:

# --- 复制必需项 ---
listen_addresses = '*'         # 允许来自备用服务器的连接
wal_level = replica            # 必须是 'replica' 或更高(例如,'logical')
max_wal_senders = 10           # 来自备用服务器的最大并发连接数
max_replication_slots = 10     # 持久复制流所需的插槽

# --- 同步提交必需项 ---
synchronous_standby_names = '1 (standby_app_name)' # 指定所需的备用服务器

# --- 可选但推荐 ---
wal_log_hints = on             # 推荐用于更安全的复制,尽管它会增加 WAL 量
shared_preload_libraries = 'pg_stat_statements' # 如果使用监控

关键参数解释:

  • wal_level = replica:这确保了足够的信息写入 WAL,以允许备用服务器重建数据库状态。对于同步提交,此级别是最低要求。
  • synchronous_standby_names:这是定义哪些备用服务器必须确认写入的核心设置。我们使用 (N (standby_name)) 语法来定义它。如果 N=1,则在事务提交之前,至少一个备用服务器必须确认写入。

B. 配置基于主机的身份验证 (pg_hba.conf)

主服务器必须允许备用服务器的复制用户连接以进行复制。

在主服务器的 pg_hba.conf 中添加一个条目:

# 类型 数据库 用户 地址 方式
host    replication     repl_user       pg_standby/32           scram-sha-256

pg_standby/32 替换为备用服务器的实际 IP 地址或子网。

C. 创建复制槽和用户

连接到主服务器上的 PostgreSQL 以创建必要的用户和复制槽。

1. 创建复制用户:

CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'a_strong_password';

2. 创建复制槽:

此槽确保 WAL 段被保留,直到备用服务器确认接收,从而防止在备用服务器暂时断开连接时发生数据丢失。

SELECT pg_create_physical_replication_slot('standby_app_name');
  • 命名注意事项:此处提供的名称 (standby_app_name) 必须与主服务器上 synchronous_standby_names 中指定的名称匹配。

D. 重启主服务器

通过重启主服务器上的 PostgreSQL 服务来应用所有配置更改。

sudo systemctl restart postgresql

步骤 2:配置备用服务器

备用服务器配置为使用恢复配置从主服务器流式传输 WAL 记录。

A. 基础备份

在开始流式传输之前,备用服务器需要主服务器数据目录的完整副本。首先停止备用服务器上的 PostgreSQL。

sudo systemctl stop postgresql

使用 pg_basebackup 进行基础备份。根据需要替换路径和连接详情:

# 使用 pg_basebackup 工具的示例
pg_basebackup -h pg_primary -D /var/lib/postgresql/15/main/ -U repl_user -P -Xs -R -W
  • -D:备用服务器上的目标数据目录。
  • -U:复制用户。
  • -P:显示进度。
  • -Xs:在基础备份期间包含必要的 WAL 文件。
  • -R:自动创建 standby.signal 文件并在 postgresql.auto.conf(或恢复配置)中生成必要的连接设置。

B. 配置备用服务器上的 postgresql.conf

在备用服务器上,确保 postgresql.conf 允许其充当副本。这里的关键设置是设置应用程序名称,它必须与主服务器上使用的槽名称匹配。

# --- 备用服务器必需项 ---
primary_conninfo = 'host=pg_primary port=5432 user=repl_user password=a_strong_password application_name=standby_app_name'
hot_standby = on          # 允许在恢复/备用模式下进行读查询

C. 启动备用服务器

启动备用服务器上的 PostgreSQL 服务。

sudo systemctl start postgresql

步骤 3:验证和测试同步提交

两台服务器都运行后,验证连接并测试同步行为。

A. 验证复制状态

连接到数据库并检查 pg_stat_replication 视图:

SELECT client_addr, application_name, state, sync_state FROM pg_stat_replication;

您应该会看到 standby_app_name 的一个条目,其 sync_statesync

B. 测试同步提交

控制 PostgreSQL 等待程度的全局参数是 synchronous_commit。对于 RPO=0,您必须使用一个强制同步的值。

1. 设置全局行为

如果您按照步骤 1 中的说明在主服务器上配置了 synchronous_standby_names,那么如果 synchronous_commit 设置为 on(默认值)或 remote_write,默认行为将强制等待所需的备用服务器。

为了获得最强的保证,请在 postgresql.conf 中明确将其设置为 remote_writeremote_apply(如果您需要备用服务器将数据刷新到磁盘,而不仅仅是接收数据)。

# 在主服务器的 postgresql.conf 中
synchronous_commit = remote_write

警告:将 synchronous_commit = remote_writeon 会显著增加事务延迟,相较于异步模式(offlocal)。这种延迟与主服务器和同步备用服务器之间的网络速度直接相关。

2. 在事务中测试

要在事务中进行测试(无需全局配置更改),您可以按会话或按事务设置:

-- 连接到主服务器

BEGIN;
SET LOCAL synchronous_commit = remote_write;

INSERT INTO sales (item, amount) VALUES ('Widget A', 100);
-- 此 INSERT 将阻塞,直到 'standby_app_name' 确认接收。

COMMIT;
-- COMMIT 仅在备用服务器确认 WAL 写入后才成功。

如果在事务期间与同步备用服务器的连接丢失,主服务器将无限期等待(如果备用服务器干净地断开连接)或根据 synchronous_commit_fallback_on_error 设置进行回退(默认为 on,这意味着如果主服务器无法确认同步状态,事务可能会失败或挂起)。

同步高可用性最佳实践

  • 使用专用备用服务器:只将物理距离近(低延迟)的备用服务器分配到您的同步复制列表中。高延迟将严重影响写入性能。
  • 监控复制延迟:即使在同步模式下,也要监控备用服务器的延迟。一个虽然技术上处于“同步”状态但处理 WAL 时间过长的慢速备用服务器仍然会影响用户体验。
  • 连接回退:理解 synchronous_commit_fallback_on_error 设置。如果设置为 off,在提交期间与同步备用服务器通信失败将导致主服务器上的事务失败,从而防止潜在的数据分歧,但会立即影响可用性。
  • 使用多个备用服务器:为了在同步设置中实现最大冗余,请配置 synchronous_standby_names = '2 (standby1, standby2)' 以要求两个不同的备用服务器进行提交。