{{< details >}}

  • Tier: 专业版, 旗舰版
  • Offering: 私有化部署

{{< /details >}}

在处理 PostgreSQL 复制和故障转移时,您可能会遇到以下问题。

Consul 和 PostgreSQL 的更改未生效

由于潜在影响,gitlab-ctl reconfigure 仅重载 Consul 和 PostgreSQL,而不重启服务。然而,并不是所有的更改都能通过重载激活。

要重启任一服务,请运行 gitlab-ctl restart SERVICE

对于 PostgreSQL,通常可以安全地默认重启领导节点。自动故障转移默认为 1 分钟超时。只要数据库在此之前返回,就无需执行其他操作。

在 Consul 服务器节点上,以受控方式重启 Consul 服务 是很重要的。

PgBouncer 错误 ERROR: pgbouncer cannot connect to server

您可能会在运行 gitlab-rake gitlab:db:configure 时遇到此错误,或者在 PgBouncer 日志文件中看到该错误。

PG::ConnectionBad: ERROR:  pgbouncer cannot connect to server

问题可能在于您的 PgBouncer 节点的 IP 地址未包含在数据库节点上的 /etc/gitlab/gitlab.rbtrust_auth_cidr_addresses 设置中。

您可以通过检查领导数据库节点上的 PostgreSQL 日志来确认这是问题所在。如果您看到以下错误,那么 trust_auth_cidr_addresses 就是问题所在。

2018-03-29_13:59:12.11776 FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "pgbouncer", database "gitlabhq_production", SSL off

要解决此问题,请将 IP 地址添加到 /etc/gitlab/gitlab.rb

postgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)

重新配置极狐GitLab 以使更改生效。

PgBouncer 节点在 Patroni 切换后不进行故障转移

由于影响 GitLab 16.5.0 之前版本的已知问题,PgBouncer 节点在 Patroni 切换后不会自动故障转移。在这个例子中,极狐GitLab 未能检测到暂停的数据库,然后尝试 RESUME 一个未暂停的数据库:

INFO -- : Running: gitlab-ctl pgb-notify --pg-database gitlabhq_production --newhost database7.example.com --user pgbouncer --hostuser gitlab-consul
ERROR -- : STDERR: Error running command: GitlabCtl::Errors::ExecutionError
ERROR -- : STDERR: ERROR: ERROR:  database gitlabhq_production is not paused

为了确保 Patroni 切换 成功,您必须手动使用以下命令在所有 PgBouncer 节点上重启 PgBouncer 服务:

gitlab-ctl restart pgbouncer

重新初始化副本

如果副本无法启动或重新加入集群,或者当它落后且无法赶上时,可能需要重新初始化副本:

  1. 检查复制状态以确认需要重新初始化哪个服务器。例如:

    + Cluster: postgresql-ha (6970678148837286213) ------+---------+--------------+----+-----------+
    | Member                              | Host         | Role    | State        | TL | Lag in MB |
    +-------------------------------------+--------------+---------+--------------+----+-----------+
    | gitlab-database-1.example.com       | 172.18.0.111 | Replica | running      | 55 |         0 |
    | gitlab-database-2.example.com       | 172.18.0.112 | Replica | start failed |    |   unknown |
    | gitlab-database-3.example.com       | 172.18.0.113 | Leader  | running      | 55 |           |
    +-------------------------------------+--------------+---------+--------------+----+-----------+
    
  2. 登录到损坏的服务器并重新初始化数据库和复制。Patroni 会关闭该服务器上的 PostgreSQL,删除数据目录,并从头开始重新初始化:

    sudo gitlab-ctl patroni reinitialize-replica --member gitlab-database-2.example.com
    

    这可以在任何 Patroni 节点上运行,但需要注意的是,sudo gitlab-ctl patroni reinitialize-replica 没有 --member 会重启运行它的服务器。您应该在损坏的服务器上本地运行,以降低意外数据丢失的风险。

  3. 监控日志:

    sudo gitlab-ctl tail patroni
    

在 Consul 中重置 Patroni 状态

{{< alert type=”warning” >}}

在 Consul 中重置 Patroni 状态是一个潜在的破坏性过程。确保您先有一个健康的数据库备份。

{{< /alert >}}

作为最后的手段,您可以在 Consul 中完全重置 Patroni 状态。

如果您的 Patroni 集群处于未知或不良状态且没有节点可以启动,可能需要这样做:

+ Cluster: postgresql-ha (6970678148837286213) ------+---------+---------+----+-----------+
| Member                              | Host         | Role    | State   | TL | Lag in MB |
+-------------------------------------+--------------+---------+---------+----+-----------+
| gitlab-database-1.example.com       | 172.18.0.111 | Replica | stopped |    |   unknown |
| gitlab-database-2.example.com       | 172.18.0.112 | Replica | stopped |    |   unknown |
| gitlab-database-3.example.com       | 172.18.0.113 | Replica | stopped |    |   unknown |
+-------------------------------------+--------------+---------+---------+----+-----------+

在删除 Consul 中的 Patroni 状态之前尝试解决 Patroni 节点上的 gitlab-ctl 错误

当第一个 Patroni 节点启动时,此过程会导致重新初始化的 Patroni 集群。

要重置 Consul 中的 Patroni 状态:

  1. 记下曾经是领导者的 Patroni 节点,或者应用程序认为是当前领导者的节点,如果当前状态显示多个或没有:
    • 在 PgBouncer 节点的 /var/opt/gitlab/consul/databases.ini 中查看,它包含当前领导者的主机名。
    • 所有 数据库节点上查看 Patroni 日志 /var/log/gitlab/patroni/current(或较旧的旋转和压缩日志 /var/log/gitlab/patroni/@40000*),看看哪个服务器最近被集群标识为领导者:

      INFO: no action. I am a secondary (database1.local) and following a leader (database2.local)
      
  2. 停止所有节点上的 Patroni:

    sudo gitlab-ctl stop patroni
    
  3. 重置 Consul 中的状态:

    /opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/
    
  4. 启动一个 Patroni 节点,它初始化 Patroni 集群以选举为领导者。强烈建议启动之前的领导者(在第一步中记录),以免丢失因集群状态损坏而未复制的现有写入:

    sudo gitlab-ctl start patroni
    
  5. 启动所有其他 Patroni 节点,以副本身份加入 Patroni 集群:

    sudo gitlab-ctl start patroni
    

如果您仍然看到问题,下一步是恢复最后一个健康的备份。

Patroni 日志中关于 127.0.0.1pg_hba.conf 条目错误

Patroni 日志中的以下日志条目表明复制未正常工作,需要进行配置更改:

FATAL:  no pg_hba.conf entry for replication connection from host "127.0.0.1", user "gitlab_replicator"

要解决此问题,请确保回环接口包含在 CIDR 地址列表中:

  1. 编辑 /etc/gitlab/gitlab.rb

    postgresql['trust_auth_cidr_addresses'] = %w(<other_cidrs> 127.0.0.1/32)
    
  2. 重新配置极狐GitLab 以使更改生效。
  3. 检查所有副本是否已同步

错误:请求的起始点超前于写入日志 (WAL) 刷新位置

Patroni 日志中的此错误表示数据库未进行复制:

FATAL:  could not receive data from WAL stream:
ERROR:  requested starting point 0/5000000 is ahead of the WAL flush position of this server 0/4000388

此示例错误来自一个最初配置错误的副本,并且从未进行过复制。

通过重新初始化副本来解决它。

Patroni 启动失败并出现 MemoryError

Patroni 可能会启动失败,并记录错误和堆栈跟踪:

MemoryError
Traceback (most recent call last):
  File "/opt/gitlab/embedded/bin/patroni", line 8, in <module>
    sys.exit(main())
[..]
  File "/opt/gitlab/embedded/lib/python3.7/ctypes/__init__.py", line 273, in _reset_cache
    CFUNCTYPE(c_int)(lambda: None)

如果堆栈跟踪以 CFUNCTYPE(c_int)(lambda: None) 结束,则此代码会触发 MemoryError, 如果 Linux 服务器已进行了安全加固。

此代码会导致 Python 写入临时可执行文件,如果它找不到文件系统来执行此操作。例如,如果 /tmp 文件系统上设置了 noexec,它会因 MemoryError 而失败。

运行 gitlab-ctl 时的错误

Patroni 节点可能会进入一种状态,在这种状态下 gitlab-ctl 命令失败, 而 gitlab-ctl reconfigure 无法修复节点。

如果这与 PostgreSQL 的版本升级同时发生,请遵循不同的程序

一个常见的症状是 gitlab-ctl 无法确定 它需要关于安装的信息,如果数据库服务器无法启动:

Malformed configuration JSON file found at /opt/gitlab/embedded/nodes/<HOSTNAME>.json.
This usually happens when your last run of `gitlab-ctl reconfigure` didn't complete successfully.
Error while reinitializing replica on the current node: Attributes not found in
/opt/gitlab/embedded/nodes/<HOSTNAME>.json, has reconfigure been run yet?

同样,节点文件 (/opt/gitlab/embedded/nodes/<HOSTNAME>.json) 应包含大量信息, 但可能仅创建:

{
  "name": "<HOSTNAME>"
}

解决此问题的以下过程包括重新初始化此副本: 当前此节点上的 PostgreSQL 状态将被丢弃:

  1. 关闭 Patroni 和(如果存在)PostgreSQL 服务:

    sudo gitlab-ctl status
    sudo gitlab-ctl stop patroni
    sudo gitlab-ctl stop postgresql
    
  2. 删除 /var/opt/gitlab/postgresql/data,以防其状态阻止 PostgreSQL 启动:

    cd /var/opt/gitlab/postgresql
    sudo rm -rf data
    

    小心此步骤以避免数据丢失。 此步骤也可以通过重命名 data/ 来实现: 确保有足够的磁盘空间来存储主数据库的新副本, 并在修复副本后删除额外目录。

  3. 在 PostgreSQL 未运行的情况下,节点文件现在可以成功创建:

    sudo gitlab-ctl reconfigure
    
  4. 启动 Patroni:

    sudo gitlab-ctl start patroni
    
  5. 监控日志并检查集群状态:

    sudo gitlab-ctl tail patroni
    sudo gitlab-ctl patroni members
    
  6. 再次运行 reconfigure

    sudo gitlab-ctl reconfigure
    
  7. 如果 gitlab-ctl patroni members 指示需要,重新初始化副本:

    sudo gitlab-ctl patroni reinitialize-replica
    

如果此过程不起作用并且集群无法选举领导者, 还有另一个修复,应仅作为最后手段使用。

PostgreSQL 主版本升级在 Patroni 副本上失败

Patroni 副本gitlab-ctl pg-upgrade 期间可能会陷入循环, 并且升级失败。

一个示例症状集如下:

  1. 定义了 postgresql 服务, 通常不应该出现在 Patroni 节点上。它存在是因为 gitlab-ctl pg-upgrade 添加它以创建一个新的空数据库:

    run: patroni: (pid 1972) 1919s; run: log: (pid 1971) 1919s
    down: postgresql: 1s, normally up, want up; run: log: (pid 1973) 1919s
    
  2. /var/log/gitlab/postgresql/current 中,PostgreSQL 生成 PANIC 日志条目, 因为 Patroni 正在删除 /var/opt/gitlab/postgresql/data 作为重新初始化副本的一部分:

    DETAIL:  Could not open file "pg_xact/0000": No such file or directory.
    WARNING:  terminating connection because of crash of another server process
    LOG:  all server processes terminated; reinitializing
    PANIC:  could not open file "global/pg_control": No such file or directory
    
  3. /var/log/gitlab/patroni/current 中,Patroni 记录以下内容。 本地 PostgreSQL 版本与集群领导者不同:

    INFO: trying to bootstrap from leader 'HOSTNAME'
    pg_basebackup: incompatible server version 12.6
    pg_basebackup: removing data directory "/var/opt/gitlab/postgresql/data"
    ERROR: Error when fetching backup: pg_basebackup exited with code=1
    

重要:当 Patroni 集群处于以下状态时,此解决方法适用:

此解决方法通过设置节点使用新的 PostgreSQL 版本完成 Patroni 副本上的 PostgreSQL 升级,然后将其重新初始化为领导者升级时创建的新集群中的副本:

  1. 检查所有节点上的集群状态以确认哪个是领导者 以及副本处于什么状态

    sudo gitlab-ctl patroni members
    
  2. 副本:检查哪个版本的 PostgreSQL 是活动的:

    sudo ls -al /opt/gitlab/embedded/bin | grep postgres
    
  3. 副本:确保节点文件正确并且 gitlab-ctl 可以运行。这解决了 如果副本也有任何这些错误,运行 gitlab-ctl 时的错误问题:

    sudo gitlab-ctl stop patroni
    sudo gitlab-ctl reconfigure
    
  4. 副本:重新链接 PostgreSQL 二进制文件到所需版本 以修复 incompatible server version 错误:

    1. 编辑 /etc/gitlab/gitlab.rb 并指定所需版本:

      postgresql['version'] = 13
      
    2. 重新配置极狐GitLab:

      sudo gitlab-ctl reconfigure
      
    3. 检查二进制文件是否已重新链接。分发的 PostgreSQL 二进制文件在主版本之间有所不同,通常会有少量不正确的符号链接:

      sudo ls -al /opt/gitlab/embedded/bin | grep postgres
      
  5. 副本:确保 PostgreSQL 为指定版本完全重新初始化:

    cd /var/opt/gitlab/postgresql
    sudo rm -rf data
    sudo gitlab-ctl reconfigure
    
  6. 副本:可选地在两个额外的终端会话中监控数据库:

    • 随着 pg_basebackup 的运行,磁盘使用量增加。跟踪副本初始化的进度:

      cd /var/opt/gitlab/postgresql
      watch du -sh data
      
    • 在日志中监控过程:

      sudo gitlab-ctl tail patroni
      
  7. 副本:启动 Patroni 以重新初始化副本:

    sudo gitlab-ctl start patroni
    
  8. 副本:完成后,从 /etc/gitlab/gitlab.rb 中删除硬编码版本:

    1. 编辑 /etc/gitlab/gitlab.rb 并删除 postgresql['version']
    2. 重新配置极狐GitLab:

      sudo gitlab-ctl reconfigure
      
    3. 检查正确的二进制文件是否已链接:

      sudo ls -al /opt/gitlab/embedded/bin | grep postgres
      
  9. 检查所有节点上的集群状态:

    sudo gitlab-ctl patroni members
    

如果需要,请在其他副本上重复此过程。

其他组件的问题

如果您遇到未在此处概述的组件问题,请务必查看其特定文档页面的故障排除部分: