PostgreSQL 17 引入了故障转移槽,增强了高可用性设置。复制槽确保在复制过程中数据在节点之间保持可靠和一致,而故障转移槽确保节点之间的一致性,特别是在故障转移期间和之后。
故障转移槽是一项强大的功能,确保逻辑复制即使在故障转移到备用服务器后也能无缝继续。使用故障转移槽可以自动同步逻辑复制槽在主节点和备用节点之间,显著减少停机时间和在故障转移期间对人工干预的需求。
本指南将带您通过使用新故障转移槽功能设置高可用性 PostgreSQL 集群。到最后,您将拥有一个强大的复制设置,能够无缝处理故障转移。
故障转移槽的重要性:从历史角度看
PostgreSQL 15 中的挑战
- 复制槽与主节点绑定:在 PostgreSQL 15 中,复制槽仅在主服务器上创建。如果主服务器发生故障,所有逻辑复制槽将丢失,导致显著的复制延迟和数据丢失。
- 手动故障转移管理:在故障转移场景中,管理员手动在新的主服务器上重新创建复制槽,这增加了复杂性,带来了错误,并延长了停机时间。
- 无插槽同步:备用服务器无法得知主服务器上的逻辑复制插槽。这种缺乏同步导致在发生故障转移时,复制流会完全重置。
PostgreSQL 16 的改进
最小逻辑解码
PostgreSQL 16引入了一项名为最小逻辑解码的功能,适用于备用服务器:
- 备用服务器上的最小解码:这使得备用服务器能够解码 WAL 日志,以便为逻辑复制做准备,在发生故障转移时启用预热插槽。
- 更快速的故障转移:通过在备用服务器上预解码 WAL 更改,可以减少将备用服务器提升为主服务器时的复制延迟。然而,这仍然需要一些手动配置,以确保故障转移的顺利进行。
PostgreSQL 17:改变游戏规则者 – 故障转移插槽
- 故障转移插槽:在 PostgreSQL 17 中引入故障转移插槽,消除了手动干预的需求,通过自动同步主服务器和备用服务器之间的逻辑复制插槽。
- 自动同步:新的插槽同步工作线程确保故障转移启用的插槽(故障转移 = true)始终保持同步,即使主节点处于活动状态。
- 无缝过渡:在故障转移时,备用服务器可以接管主服务器的角色,而不会丢失任何复制槽,确保零数据丢失和持续复制。
功能 |
PostgreSQL 15 |
PostgreSQL 16 |
PostgreSQL 17 |
---|---|---|---|
逻辑复制 |
是 |
是 |
是 |
自动复制槽同步 |
否 |
备用服务器上的最小逻辑解码 |
完全故障转移槽 |
故障转移处理 |
需要手动干预 |
备用服务器上的预热槽 |
自动故障转移槽 |
同步复制槽到备用服务器 |
不支持 |
最小化,需要配置 |
带有 slotsync 工作线程的自动化 |
逻辑复制的高可用性 |
有限 |
通过最小解码改进 |
无缝故障转移插槽 |
创建具有故障转移插槽的高可用性集群
本节将指导您创建一个带有故障转移插槽的 PostgreSQL 高可用性集群。在我们的示例中,我们将使用以下节点:
- NodeA(主服务器)
- NodeB(物理备用)
- NodeC(逻辑订阅者)
先决条件
在开始之前,请确保您拥有:
- 在所有三个节点上安装了 PostgreSQL 17。
- 节点之间无密码 SSH 访问。
- 对 PostgreSQL、PostgreSQL 复制和 PostgreSQL 配置文件有基本了解。
第 1 步:配置主节点(NodeA)
1.1 在NodeA上初始化集群
在主节点安装完PostgreSQL后,初始化集群;您可以使用以下命令:
mkdir -p /home/pgedge/nodeA
initdb -D /home/pgedge/nodeA --no-locale -E UTF8
pg_ctl -D /home/pgedge/nodeA -l /home/pgedge/logs/nodeA.log start
1.2 在postgresql.conf文件中配置复制
初始化集群后,编辑postgresql.conf
文件,该文件默认位于/home/pgedge/nodeA/postgresql.conf
。设置以下参数值:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
synchronous_standby_names = '*'
synchronized_standby_slots = 'sb1_slot'
port = 5432
1.3 更新pg_hba.conf文件以允许复制访问
pg_hba.conf文件管理PostgreSQL服务器的客户端身份验证。在/home/pgedge/nodeA/pg_hba.conf
中添加以下条目以确保复制用户的访问:
host replication replicator 127.0.0.1/32 md5
然后,重新加载配置:
pg_ctl -D /home/pgedge/nodeA reload
1.4 创建一个复制用户
然后,登录到PostgreSQL并创建复制用户:
psql -d postgres -p 5432
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicator_password';
1.5 创建一个表并设置发布
接下来,您需要创建一个表并创建一个关联的发布:
CREATE TABLE foo (c1 INT PRIMARY KEY);
GRANT SELECT ON foo TO replicator;
CREATE PUBLICATION mypub FOR TABLE foo;
第2步:配置物理备用(NodeB)
2.1 初始化NodeB
安装完PostgreSQL后,初始化NodeB:
mkdir -p /home/pgedge/nodeB
initdb -D /home/pgedge/nodeB --no-locale -E UTF8
pg_ctl -D /home/pgedge/nodeB -l /home/pgedge/logs/nodeB.log start
2.1 创建基础备份
然后,使用pg_basebackup来备份集群:
mkdir -p /home/pgedge/nodeB
pg_basebackup -D /home/pgedge/nodeB -R -X stream -P -h localhost -p 5432 -U replicator
2.2 在Node-B上配置postgresql.conf
修改postgresql.conf
文件(位于/home/pgedge/nodeB/postgresql.conf
),设置:
port = 5433
primary_conninfo = 'host=localhost port=5432 user=replicator password=replicator_password dbname=postgres application_name=sb1_slot'
primary_slot_name = 'sb1_slot'
hot_standby_feedback = on
sync_replication_slots = on
2.3 启用故障转移插槽同步
使用psql客户端登录到NodeB:
psql -d postgres -p 5433
然后,使用以下语句配置NodeB的复制:
ALTER SYSTEM SET sync_replication_slots = on;
ALTER SYSTEM SET hot_standby_feedback = on;
ALTER SYSTEM SET synchronized_standby_slots = 'sb1_slot';
退出psql
客户端并重新启动NodeB:
pg_ctl -D /home/pgedge/nodeB restart
2.4 验证插槽同步
然后,使用psql
重新连接到NodeB,并验证插槽是否同步:
SELECT slot_name, failover, synced FROM pg_replication_slots;
第3步:设置逻辑订阅者(NodeC)
3.1 初始化集群并配置NodeC
安装完PostgreSQL后,初始化集群;您可以使用以下命令:
mkdir -p /home/pgedge/nodeC
initdb -D /home/pgedge/nodeC --no-locale -E UTF8
然后,编辑/home/pgedge/nodeC/postgresql.conf
文件,设置以下参数值:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
sync_replication_slots = on
port = 5444
After editing the configuration file, start NodeC:
pg_ctl -D /home/pgedge/nodeC -l /home/pgedge/logs/nodeC.log start
3.2 在NodeC上创建订阅
使用以下命令在NodeC上创建订阅:
CREATE SUBSCRIPTION foosub CONNECTION 'dbname=postgres host=localhost port=5432 user=replicator password=replicator_password' PUBLICATION mypub WITH (failover = true);
第4步:模拟故障转移并确保连续性
您可以使用以下命令模拟故障转移并确认复制持续进行且数据完整性得到保留。
4.1 模拟故障转移
使用以下命令模拟NodeA的故障,然后将NodeB从备用提升为主服务器:
pg_ctl -D /home/pgedge/nodeA stop
pg_ctl -D /home/pgedge/nodeB promote
4.2 更新NodeC上的订阅
将NodeB升级后,登录NodeC并更新连接以反映NodeB现在是主节点:
ALTER SUBSCRIPTION foosub DISABLE;
ALTER SUBSCRIPTION foosub CONNECTION 'dbname=postgres host=localhost port=5433 user=replicator password=replicator_password';
ALTER SUBSCRIPTION foosub ENABLE;
4.3 验证数据连续性
为了测试复制,请使用psql
登录到Node-B(现在是主节点):
INSERT INTO foo VALUES (3), (4);
检查Node-C上的复制:
SELECT * FROM foo;
结论
PostgreSQL 17 的故障转移插槽功能允许在逻辑复制环境中实现无缝故障转移。遵循本指南中概述的步骤,您可以创建一个确保在主服务器故障期间数据流不间断的高可用性集群。
通过优化配置并利用PostgreSQL 17的新功能,您可以为重要应用程序创建一个具有弹性和高效性的数据库基础设施。
Source:
https://dzone.com/articles/setting-up-failover-slots-in-postgresql-17