这里是文章模块栏目内容页
用repmgr 实现postgresql集群一主多从备份

repmgr

本文档主要集中在Repmgr的功能调查上,详细的配置参数和部分原理并为进行编写,有需要的朋友可以自行仔细查看。

repmgr入门

概念

repmgr使用以下术语:

  • 复制群集
    “复制集群”是指通过流复制连接的PostgreSQL服务


  • 节点
    节点是复制群集中的单个PostgreSQL服务器

  • 上游节点
    备用服务器连接的目标节点,以便接收流式复制。通常是主服务器,或者在级联复制的情况下,是另一个备用服务器。

  • 故障转移
    这是在主服务器发生故障并且将适当的备用服务器提升为新主服务器时发生的操作。该repmgrd守护进程支持自动切换,并且停机时间最小化。

  • 切换
    在某些情况下,例如硬件或操作系统维护,必须使主服务器脱离工作; 在这种情况下,需要受控切换,从而提升备节点,并且以受控方式从复制群集中移除现有主节点。repmgr命令行提供此功能。

  • 围栏
    在故障转移的情况下,在备用数据库提升主之后,前一主数据库不会意外地重新上线,上线将导致脑裂的情况。为了防止这种情况,应将失败的主数据库与应用程序隔离。

  • 见证服务器
    repmgr提供了设置所谓的“见证服务器”的功能,以帮助确定具有多个备用数据库的故障转移情况下的新主服务器。见证服务器本身不是复制集群的一部分,但它包含repmgr元数据的副本。

见证服务器的目的是提供“投票”,其中复制群集中的服务器分布在多个位置。在服务器之间失去连接的情况下,见证服务器的存在或不存在将决定该位置的服务器是否被提升为主要服务器,这是为了防止“裂脑”情况,其中隔离网络中的主将失败并提升备。

如果 正在使用repmgrd,则只需要创建见证服务器。

组件

repmgr是一套开源工具,用于管理PostgreSQL服务器集群中的复制和故障转移。它支持并增强了PostgreSQL的内置流复制,它提供单个读/写主服务器和一个或多个只读备用数据库,其中包含主服务器数据库的近实时副本。它提供了两个主要工具:

  • repmgr
    用于执行管理任务的命令行工具,例如:

  1. 设置备用服务器

  2. 将备用服务器升级为主服务器

  3. 切换主服务器和备用服务器

  4. 显示复制群集中的服务器状态

  • repmgrd
    一个守护程序,它主动监视复制集群中的服务器并执行以下任务:

  1. 监控和记录复制性能

  2. 通过检测主服务器故障并提升最合适的备用服务器来执行故障转移

  3. 将有关群集中事件的通知提供给用户定义的脚本,该脚本可以执行诸如通过电子邮件发送警报等任务

Repmgr用户和元数据

为了有效地管理复制集群,repmgr需要在专用数据库中存储有关集群中服务器的信息。此模式由repmgr扩展自动创建,并包含以下对象:

  1. repmgr.events:记录感兴趣的事件

  2. repmgr.nodes:复制群集中每个服务器的连接和状态信息

  3. repmgr.monitoring_history:repmgrd编写的历史备用监视信息

  • 视图

  1. repmgr.show_nodes:基于表repmgr.nodes,另外显示服务器上游节点的名称

  2. repmgr.replication_status:启用repmgrd的监视时,显示每个备用数据库的当前监视状态。

该repmgr元数据可以存储在现有的数据库或在自己的专用数据库。请注意,repmgr元数据不能存储在不属于repmgr管理的复制集群的数据库服务器上。

数据库用户必须可供repmgr访问此数据库并执行必要的更改。此用户不需要是超级用户,但是某些操作(如repmgr扩展的初始安装)将需要超级用户连接(可以使用命令行在需要时指定 –superuser)。

安装Repmgr的要求

  1. repmgr是在Linux和OS X上开发和测试的,适用于PostgreSQL本身支持的任何类UNIX系统。不支持Microsoft Windows

  2. 复制群集中的所有服务器必须运行相同的主要版本的PostgreSQL,我们建议它们也运行相同的次要版本。

repmgr安装

  • 从包安装
    查自己对应的操作系统的方法就可以


  • 从源代码安装
    git clone https://github.com/2ndQuadrant/repmgr获取源代码./configure && make install安装repmgr

快速入门指南

使用repmgr设置集群基本复制的条件

以下部分将介绍如何使用repmgr 命令行工具设置具有主服务器和备用服务器的基本复制群集。

我们假设node1主数据库使用ip为192.168.1.11,node2 备用数据库ip为192.168.1.12

必须在两台服务器上安装以下软件:
1. PostgreSQL
2. repmgr(匹配已安装的 PostgreSQL主版本)

在网络级别,PostgreSQL端口之间的连接(默认值:) 5432必须在两个方向上都可以。

如果希望repmgr复制位于PostgreSQL数据目录之外的配置文件和/或测试 switchover 功能,则还需要在两个服务器之间建立无密码SSH连接,并且 应安装rsync。

PostgreSQL设置

max_wal_senders = 10
max_replication_slots = 10
wal_level = 'hot_standby'
hot_standby = on

创建repmgr用户和数据库

createuser -s repmgr
createdb repmgr -O repmgr

配置pg_hba.conf

local   replication   repmgr                              trust
host    replication   repmgr      127.0.0.1/32            trust
host    replication   repmgr      192.168.1.0/24          trust

local   repmgr        repmgr                              trust
host    repmgr        repmgr      127.0.0.1/32            trust
host    repmgr        repmgr      192.168.1.0/24          trust

准备备机

备机不创建PostgreSQL实例(不执行initdb),但是要确保数据目录存在,并且权限必须设置0700(drwx——),repmgr会从主节点拷贝数据至这个目录,如果数据目录存在pg实例那么将失败。

psql 'host=node1 user=repmgr dbname=repmgr connect_timeout=2'在备机检查是否可以连接到主节点

repmgr配置文件

在主节点创建repmgr.conf并且至少包含如下内容

    node_id=1
    node_name=node1
    conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
    data_directory='/var/lib/postgresql/data'

repmgr.conf应该存储到数据目录中,它会被重写当设置的时候或是重新初始化PostgreSQL服务的时候,

注册主服务器

要使repmgr支持复制集群,必须使用repmgr注册主节点。这将安装repmgr 扩展和元数据对象,并为主服务器添加元数据记录:

$ repmgr -f /etc/repmgr.conf primary register
    INFO: connecting to primary database...
    NOTICE: attempting to install extension "repmgr"
    NOTICE: "repmgr" extension successfully installed
    NOTICE: primary node record (id: 1) registered

验证群集的状态,如下所示:

 repmgr -f /etc/repmgr.conf cluster show
     ID | Name  | Role    | Status    | Upstream | Connection string
    ----+-------+---------+-----------+----------+--------------------------------------------------------
     1  | node1 | primary | * running |          | host=node1 dbname=repmgr user=repmgr connect_timeout=2

repmgr元数据表中 的记录如下所示:

repmgr=# SELECT * FROM repmgr.nodes;
    -[ RECORD 1 ]----+-------------------------------------------------------
    node_id          | 1
    upstream_node_id |
    active           | t
    node_name        | node1
    type             | primary
    location         | default
    priority         | 100
    conninfo         | host=node1 dbname=repmgr user=repmgr connect_timeout=2
    repluser         | repmgr
    slot_name        |
    config_file      | /etc/repmgr.conf

复制群集中的每个服务器都有自己的记录。如果repmgrd 在使用会体现在upstream_node_id,active和type将在发生变化时进行更新。

克隆备服务器

在备用服务器上创建repmgr.conf文件。例如:

    node_id=2
    node_name=node2
    conninfo='host=node2 user=repmgr dbname=repmgr connect_timeout=2'
    data_directory='/var/lib/postgresql/data'

使用–dry-run检测备机可以创建

    $ repmgr -h node1 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --dry-run
    NOTICE: using provided configuration file "/etc/repmgr.conf"
    NOTICE: destination directory "/var/lib/postgresql/data" provided
    INFO: connecting to source node
    NOTICE: checking for available walsenders on source node (2 required)
    INFO: sufficient walsenders available on source node (2 required)
    NOTICE: standby will attach to upstream node 1
    HINT: consider using the -c/--fast-checkpoint option
    INFO: all prerequisites for "standby clone" are met

如果检测没有问题,可以创建备机:

    $ repmgr -h node1 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone

    NOTICE: using configuration file "/etc/repmgr.conf"
    NOTICE: destination directory "/var/lib/postgresql/data" provided
    INFO: connecting to source node
    NOTICE: checking for available walsenders on source node (2 required)
    INFO: sufficient walsenders available on source node (2 required)
    INFO: creating directory "/var/lib/postgresql/data"...
    NOTICE: starting backup (using pg_basebackup)...
    HINT: this may take some time; consider using the -c/--fast-checkpoint option
    INFO: executing:
      pg_basebackup -l "repmgr base backup" -D /var/lib/postgresql/data -h node1 -U repmgr -X stream
    NOTICE: standby clone (using pg_basebackup) complete
    NOTICE: you can now start your PostgreSQL server
    HINT: for example: pg_ctl -D /var/lib/postgresql/data start

使用PostgreSQL的pg_basebackup实用程序克隆了node1上主服务器的PostgreSQL数据目录文件。recovery.conf文件将被自动创建。
默认情况下,主数据目录中的所有配置文件都将复制到备用数据库。通常postgresql.conf, postgresql.auto.conf,pg_hba.conf和 pg_ident.conf。在备用数据库启动之前,可能需要进行修改。

验证复制是否正常

连接主节点并执行:

     repmgr=# SELECT * FROM pg_stat_replication;
    -[ RECORD 1 ]----+------------------------------
    pid              | 19111
    usesysid         | 16384
    usename          | repmgr
    application_name | node2
    client_addr      | 192.168.1.12
    client_hostname  |
    client_port      | 50378
    backend_start    | 2017-08-28 15:14:19.851581+09
    backend_xmin     |
    state            | streaming
    sent_location    | 0/7000318
    write_location   | 0/7000318
    flush_location   | 0/7000318
    replay_location  | 0/7000318
    sync_priority    | 0
    sync_state       | async

这表明先前克隆的备用数据库(node2在 application_name显示)已从IP地192.168.1.12址连接到主数据库

注册备服务器

注册备服务器使用如下命令:

    repmgr -f /etc/repmgr.conf standby register
    NOTICE: standby node "node2" (ID: 2) successfully registered

检查节点信息

    $ repmgr -f /etc/repmgr.conf cluster show
     ID | Name  | Role    | Status    | Upstream | Location | Connection string
    ----+-------+---------+-----------+----------+----------+--------------------------------------
     1  | node1 | primary | * running |          | default  | host=node1 dbname=repmgr user=repmgr
     2  | node2 | standby |   running | node1    | default  | host=node2 dbname=repmgr user=repmgr

使用repmgrd

repmgrd概述

repmgrd(“ replication manager daemon”)是一个管理和监视的守护程序,它在复制集群中的每个节点上运行。它可以自动执行故障转移和更新备用数据库等操作,以跟踪新的主数据库,并提供有关每个备用数据库状态的监视信息。

repmgrd 提供的功能包括:
1. 多种配置选项
2. 执行自定义脚本
3. 通过一个命令暂停所有节点的repmgrd
4. 可选是否设置见证服务器
5. 位置设置,限制节点的提升(通常多数据中心)
6. 可选择的确定节点可用性的方法
7. 保留监测统计数据(可选)

repmgrd示范

要演示自动故障转移,请设置一个3节点复制集群(一个主节点和两个备用节点直接从主节点流式传输),以便集群看起来像这样:

    $ repmgr -f /etc/repmgr.conf cluster show --compact
     ID | Name  | Role    | Status    | Upstream | Location | Prio.
    ----+-------+---------+-----------+----------+----------+-------
     1  | node1 | primary | * running |          | default  | 100
     2  | node2 | standby |   running | node1    | default  | 100
     3  | node3 | standby |   running | node1    | default  | 100

在每个数据库上启动repmgrd,并通过检查日志输出来验证它是否正在运行,日志输出在日志级别INFO如下所示:

    [2019-03-15 06:32:05] [NOTICE] repmgrd (repmgrd 4.3) starting up
    [2019-03-15 06:32:05] [INFO] connecting to database "host=node2 dbname=repmgr user=repmgr connect_timeout=2"
    INFO:  set_repmgrd_pid(): provided pidfile is /var/run/repmgr/repmgrd-11.pid
    [2019-03-15 06:32:05] [NOTICE] starting monitoring of node "node2" (ID: 2)
    [2019-03-15 06:32:05] [INFO] monitoring connection to upstream node "node1" (ID: 1)

每个repmgrd也应该将其成功启动记录为事件:

    $ repmgr -f /etc/repmgr.conf cluster event --event=repmgrd_start
     Node ID | Name  | Event         | OK | Timestamp           | Details
    ---------+-------+---------------+----+---------------------+--------------------------------------------------------
     3       | node3 | repmgrd_start | t  | 2019-03-14 04:17:30 | monitoring connection to upstream node "node1" (ID: 1)
     2       | node2 | repmgrd_start | t  | 2019-03-14 04:11:47 | monitoring connection to upstream node "node1" (ID: 1)
     1       | node1 | repmgrd_start | t  | 2019-03-14 04:04:31 | monitoring cluster primary "node1" (ID: 1)

停止主服务器:

    pg_ctl -D /var/lib/postgresql/data -m immediate stop

这将迫使主服务器立即关闭,中止所有进程和事务。这会导致repmgrd日志文件中出现一系列活动,因为每个repmgrd都会检测到主服务器的故障并做出故障转移决策。

    $ repmgr -f /etc/repmgr.conf cluster show --compact
     ID | Name  | Role    | Status    | Upstream | Location | Prio.
    ----+-------+---------+-----------+----------+----------+-------
     1  | node1 | primary | - failed  |          | default  | 100
     2  | node2 | primary | * running |          | default  | 100
     3  | node3 | standby |   running | node2    | default  | 100

使用见证服务器

见证服务器是一个正常的PostgreSQL实例,不是流复制群集的一部分; 其目的是,如果发生故障转移情况,则提供证明它是主服务器本身不可用的证据,而不是例如在不同物理位置之间的网络分裂。

见证服务器的典型用例是双节点流复制设置,其中主要和备用服务器位于不同的位置(数据中心)。通过在与主服务器相同的位置(数据中心)中创建见证服务器,如果主服务器变得不可用,则备用服务器可以决定是否可以在不“脑裂”情况的情况下提升为主:如果它无法看到见证人或主服务器,它可能存在网络级中断,它不应该提升为主。如果它可以看到见证人但不能看到主节点,这证明没有网络中断且主本身不可用,因此它可以提升自己为主。

对于更复杂的复制方案,例如使用多个数据中心,最好使用基于位置的故障转移,这可确保只有与主服务器位于同一位置的节点才能成为主节点。

要创建见证服务器,请在与群集的主服务器位于同一物理位置的服务器上设置普通的PostgreSQL实例。不应该在与主服务器同一个物理主机创建见证服务器,否则如果主服务器由于硬件问题失败,见证服务器会失效。

见证服务器的配置方式与普通的 repmgr节点相同

repmgr -f /etc/repmgr.conf witness register -h node1

使用repmgrd处理网络问题

复制群集设置的常见模式是将服务器分布在多个数据中心上。这可以提供诸如地理分布的只读副本和DR(灾难恢复能力)之类的好处。然而,这也意味着在数据中心位置之间存在网络级别断开连接的风险,如果辅助数据中心中的服务器不能连接到主服务器并提升备用数据库为主数据库,则会导致裂脑情况。

repmgr4引入了location概念:每个节点都与一个任意位置字符串相关联(默认为 default),例如:

    node_id=1
    node_name=node1
    conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'
    data_directory='/var/lib/postgresql/data'
    location='dc1'

在故障转移情况下,repmgrd将检查与当前主节点位于同一位置的其他服务器是否可见。如果有,则提升同一位置的其他节点。如果没有,repmgrd 将假定网络中断并且不提升任何其他位置的任何节点。

主可见性共识

在更复杂的复制设置中,特别是在多个数据中心之间进行复制的情况下,有些备用数据库都可能与主数据库断开,有的备与主数据库连接正常。

在这种情况下,通常不希望任何已被切断连接的备用设备启动故障转移(不会被用作故障转移,会进入降级的监视节点,等待主节点重新出现),因为主设备仍在运行且其他备数据库已连接到主数据库。4.4开始引入主可见性共识,是通过轮询每个备用数据库上次查看主数据库的时间来完成的; 如果有人在最近看过主要版本,那么推断主要版本仍然可用并且不应该启动故障转移是合理的。

$ repmgr -f /etc/repmgr.conf daemon status
 ID | Name  | Role    | Status    | Upstream | repmgrd | PID   | Paused? | Upstream last seen
----+-------+---------+-----------+----------+---------+-------+---------+--------------------
 1  | node1 | primary | * running |          | running | 96563 | no      | n/a
 2  | node2 | standby |   running | node1    | running | 96572 | no      | 1 second(s) ago
 3  | node3 | standby |   running | node1    | running | 96584 | no      | 0 second(s) ago

故障转移时备用断开连接

如果standby_disconnect_on_failover设置为true在repmgr.conf中,则在故障转移情况下,repmgrd将在做出故障转移决定之前强行断开本地节点的WAL接收器。

注意:standby_disconnect_on_failover可以从PostgreSQL 9.5及更高版本获得。此外,这要求repmgr数据库用户是超级用户。

通过这样做,可以确保在做出故障转移决策时,没有节点从主服务器接收数据,并且它们的LSN位置将是静态的。

重要:
standby_disconnect_on_failover 必须在所有节点上设置为相同的值。
在故障转移操作之后,无论结果如何,每个节点都将重新连接其WAL接收器。
如果使用standby_disconnect_on_failover,我们建议也使用primary_visibility_consensus选项。

故障转移验证

从repmgr 4.3开始,repmgr可以为repmgrd提供一个脚本,在故障转移情况下,它将由已被选择为新主节点的节点执行,以确认该节点是否应该被实际提升或是执行一些其他操作。

在repmgr.conf:

      failover_validation_command=/path/to/script.sh %n %a

%n参数将替换为节点ID(node ID), %a将替换为节点名称(node name)

此脚本必须返回退出代码,0以指示节点应该自我提升。任何其他值将导致促销中止并且选举重新运行。

repmgrd和级联复制

在PostgreSQL 9.2中引入了级联复制 – 备用数据库可以连接到上游节点而不是主服务器。repmgr和 repmgrd通过跟踪备服务器之间的关系来支持级联复制 – 每个节点记录其上游(“父”)服务器的节点id(当然主服务器除外)。

在主节点发生故障并且提升顶级备用数据库(备机的最上游节点)的故障转移情况下,连接到另一个备用数据库的备用节点不会受到影响并继续正常工作(即使它连接的上游备用数据库成为主节点)。但是,如果节点的直接上游失败,则“级联备服务器”将尝试重新连接到该节点的父节点(除非failover设置为manual在 repmgr.conf中)。