Linux 软件包安装实例上的 PostgreSQL 副本和故障转移故障排查

Consul 和 PostgreSQL 更改未生效

由于潜在的影响,gitlab-ctl reconfigure 只会重新加载 Consul 和 PostgreSQL,不会重启服务。但是,并非所有更改都可以通过重新加载来激活。

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

对于 PostgreSQL,默认情况下重启 leader 节点通常是安全的。自动故障转移默认为 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.rb 中的 trust_auth_cidr_addresses 设置中。

您可以通过检查 leader 数据库节点上的 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 以使更改生效。

重新初始化副本

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

  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 节点上运行,但请注意,不带 --membersudo gitlab-ctl patroni reinitialize-replica 将重新初始化运行它的服务器。建议在损坏的服务器上本地运行它,减少意外数据丢失的风险。

  3. 监控日志:

    sudo gitlab-ctl tail patroni
    

在 Consul 中重置 Patroni 状态

caution这是一个破坏性的过程,可能会导致集群进入不良状态。在运行此过程之前,请确保您有一个健康的备份。

作为最后的手段,如果您的 Patroni 集群处于未知/坏状态并且没有节点可以启动,您可以在 Consul 中完全重置 Patroni 状态,从而在第一个 Patroni 节点启动时重新初始化 Patroni 集群。

要在 Consul 中重置 Patroni 状态:

  1. 如果当前状态显示不止一个,或者没有,记下作为 leader 的 Patroni 节点,或者应用程序认为的当前 leader。一种方法是查看 /var/opt/gitlab/consul/databases.ini 中的 PgBouncer 节点,其中包含当前 leader 的主机名。
  2. 在所有节点上停止 Patroni:

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

    /opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/
    
  4. 启动一个 Patroni 节点,它初始化 Patroni 集群并选举为 leader。强烈建议启动前一个 leader(在第一步中注明),以免丢失由于集群状态损坏而可能尚未复制的现有写入:

    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. 检查所有副本都已同步

Patroni 日志中的错误:the requested start point is ahead of the WAL flush position

此错误表明数据库未在复制:

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)结尾,如果 Linux 服务器已进行安全加固,则此代码触发 MemoryError

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

解决方法:

  • /tmp/var/tmp 等文件系统的挂载选项中删除noexec
  • 如果设置为 enforcing,SELinux 也可能会阻止这些操作。通过将 SELinux 设置为 permissive 来验证问题是否已解决。

自 13.1 以来,Patroni 一直随 Linux 软件包以及 Python 3.7 版本一起提供。当 GitLab 14.x 开始与更高版本的 Python 一起发布时,应该不再需要变通方法,因为导致此问题的代码已从 Python 3.8 中删除。

其它组件的问题

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