将独立实例转换为 Patroni 集群
原始页面: https://patroni.readthedocs.io/en/latest/existing_data.html
本节介绍将独立 PostgreSQL 实例转换为 Patroni 集群的操作流程。
如需从零开始部署 Patroni 集群(不使用已有 PostgreSQL 实例),请参阅 运行与配置。
操作步骤
以下是将现有 PostgreSQL 集群转换为 Patroni 托管集群的步骤概览。本步骤假设现有集群的所有节点当前均在运行,并且您不打算在迁移过程中修改 PostgreSQL 配置。具体步骤如下:
按照 Patroni 配置中 认证 章节的说明创建 PostgreSQL 用户。下方代码块中提供了创建用户的示例 SQL 命令,请根据您的实际环境替换用户名和密码。如果相关用户已存在,可跳过此步骤。
-- Patroni 超级用户 -- 请将 PATRONI_SUPERUSER_USERNAME 和 PATRONI_SUPERUSER_PASSWORD 替换为实际值 CREATE USER PATRONI_SUPERUSER_USERNAME WITH SUPERUSER ENCRYPTED PASSWORD 'PATRONI_SUPERUSER_PASSWORD'; -- Patroni 复制用户 -- 请将 PATRONI_REPLICATION_USERNAME 和 PATRONI_REPLICATION_PASSWORD 替换为实际值 CREATE USER PATRONI_REPLICATION_USERNAME WITH REPLICATION ENCRYPTED PASSWORD 'PATRONI_REPLICATION_PASSWORD'; -- Patroni rewind 用户(若您打算在 Patroni 配置中启用 use_pg_rewind) -- 请将 PATRONI_REWIND_USERNAME 和 PATRONI_REWIND_PASSWORD 替换为实际值 CREATE USER PATRONI_REWIND_USERNAME WITH ENCRYPTED PASSWORD 'PATRONI_REWIND_PASSWORD'; GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO PATRONI_REWIND_USERNAME; GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO PATRONI_REWIND_USERNAME; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO PATRONI_REWIND_USERNAME; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO PATRONI_REWIND_USERNAME;在所有 PostgreSQL 节点上依次执行以下操作。请逐节点完成所有步骤后再处理下一个节点,先从主库开始,然后依次处理各从库节点:
- 如果 PostgreSQL 通过 systemd 管理,请先禁用 PostgreSQL 的 systemd 服务单元——因为 PostgreSQL 的启停将改由 Patroni 负责管理。
- 为 Patroni 创建 YAML 配置文件。可使用 Patroni 配置生成与校验工具 完成此操作。
- 注意(仅适用于主库): 如果现有集群成员之间使用复制槽进行复制,建议启用
use_slots并通过slots配置项将现有复制槽设为永久槽。请注意,当use_slots启用时,Patroni 会自动为成员间复制创建复制槽,并删除它无法识别的复制槽。此处使用永久槽的目的是在迁移至 Patroni 的过程中保留现有复制槽。详情请参阅 动态配置项。
- 注意(仅适用于主库): 如果现有集群成员之间使用复制槽进行复制,建议启用
- 通过
patronisystemd 服务单元启动 Patroni。Patroni 将自动检测到 PostgreSQL 已在运行,并开始监控该实例。
将 PostgreSQL 的"启动控制权"移交给 Patroni。为此,需要通过
patronictl restart cluster-name member-name命令重启各集群成员。为最大限度减少停机时间,建议将此步骤拆分为:- 立即重启从库节点。
- 在维护窗口内计划性地重启主库。
如果您在第 2.2 步中配置了永久槽,应在 Patroni 创建的复制槽的
restart_lsn追上对应成员原始槽的restart_lsn之后,通过patronictl edit-config cluster-name命令将其从slots配置中移除。移除后,Patroni 将在这些原始槽不再被需要时自动将其删除。以下是用于比较两个槽restart_lsn的示例查询:-- 假设 original_slot_for_member_x 是原集群中用于向成员 X 复制变更的槽名称, -- slot_for_member_x 是 Patroni 为同一目的创建的槽名称。 -- 需要确认 slot_for_member_x 的 restart_lsn >= original_slot_for_member_x 的 restart_lsn SELECT slot_name, restart_lsn FROM pg_replication_slots WHERE slot_name IN ( 'original_slot_for_member_x', 'slot_for_member_x' )
PostgreSQL 大版本升级
目前,进行大版本升级的唯一可行方式是:
- 停止 Patroni。
- 升级 PostgreSQL 二进制文件,并在主库上执行 pg_upgrade。
- 更新
patroni.yml。 - 从 DCS 中删除
initialize键,或清除 DCS 中的完整集群状态。后者可通过执行patronictl remove cluster-name命令完成。这是必要的,因为pg_upgrade会运行initdb,从而创建一个具有新 PostgreSQL 系统标识符的新数据库。 - 如果您在上一步中清除了集群状态,建议将旧数据目录中的
patroni.dynamic.json复制到新数据目录,以保留之前设置的 PostgreSQL 参数。 - 在主库上启动 Patroni。
- 在从库节点上升级 PostgreSQL 二进制文件,更新
patroni.yml,并清空data_dir。 - 在从库节点上启动 Patroni,等待复制完成。
PostgreSQL 不支持在从库节点上运行 pg_upgrade。如果您清楚自己在做什么,也可以尝试 https://www.postgresql.org/docs/current/pgupgrade.html 中描述的 rsync 方式,以替代清空从库节点 data_dir 的操作。但最安全的方式仍然是让 Patroni 为您完成数据复制。
常见问题
Patroni 启动时报错,提示无法绑定到 PostgreSQL 端口。
请核查
postgresql.conf中的listen_addresses和port配置,以及patroni.yml中的postgresql.listen配置。同时不要忘记确认pg_hba.conf中允许相应的访问。请求 Patroni 重启节点后,PostgreSQL 报错:
could not open configuration file "/etc/postgresql/10/main/pg_hba.conf": No such file or directory这个问题可能由多种原因引起,具体取决于您管理 PostgreSQL 配置的方式。如果您指定了
postgresql.config_dir,Patroni 只会在引导新集群时,根据 bootstrap 章节中的配置生成pg_hba.conf。在当前场景中,由于PGDATA非空,引导过程并未发生,因此该文件必须事先存在。