Linux 软件包安装实例上的 PostgreSQL 副本和故障转移故障排查
Tier: 专业版, 旗舰版
Offering: 私有化部署
在处理 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 日志文件中看到该错误。
plaintextPG::ConnectionBad: ERROR: pgbouncer cannot connect to server
问题可能在于您的 PgBouncer 节点的 IP 地址未包含在数据库节点上的 /etc/gitlab/gitlab.rb 的 trust_auth_cidr_addresses 设置中。
您可以通过检查领导数据库节点上的 PostgreSQL 日志来确认这是问题所在。如果您看到以下错误,那么 trust_auth_cidr_addresses 就是问题所在。
plaintext2018-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。
rubypostgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)
重新配置极狐GitLab 以使更改生效。
PgBouncer 节点在 Patroni 切换后不进行故障转移
由于影响 GitLab 16.5.0 之前版本的已知问题,PgBouncer 节点在 Patroni 切换后不会自动故障转移。在这个例子中,极狐GitLab 未能检测到暂停的数据库,然后尝试 RESUME 一个未暂停的数据库:
plaintextINFO -- : 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 服务:
shellgitlab-ctl restart pgbouncer
重新初始化副本
如果副本无法启动或重新加入集群,或者当它落后且无法赶上时,可能需要重新初始化副本:
-
检查复制状态以确认需要重新初始化哪个服务器。例如:
plaintext1+ Cluster: postgresql-ha (6970678148837286213) ------+---------+--------------+----+-----------+ 2| Member | Host | Role | State | TL | Lag in MB | 3+-------------------------------------+--------------+---------+--------------+----+-----------+ 4| gitlab-database-1.example.com | 172.18.0.111 | Replica | running | 55 | 0 | 5| gitlab-database-2.example.com | 172.18.0.112 | Replica | start failed | | unknown | 6| gitlab-database-3.example.com | 172.18.0.113 | Leader | running | 55 | | 7+-------------------------------------+--------------+---------+--------------+----+-----------+ -
登录到损坏的服务器并重新初始化数据库和复制。Patroni 会关闭该服务器上的 PostgreSQL,删除数据目录,并从头开始重新初始化:
shellsudo gitlab-ctl patroni reinitialize-replica --member gitlab-database-2.example.com这可以在任何 Patroni 节点上运行,但需要注意的是,sudo gitlab-ctl patroni reinitialize-replica 没有 --member 会重启运行它的服务器。您应该在损坏的服务器上本地运行,以降低意外数据丢失的风险。
-
监控日志:
shellsudo gitlab-ctl tail patroni
在 Consul 中重置 Patroni 状态
作为最后的手段,您可以在 Consul 中完全重置 Patroni 状态。
如果您的 Patroni 集群处于未知或不良状态且没有节点可以启动,可能需要这样做:
plaintext1+ Cluster: postgresql-ha (6970678148837286213) ------+---------+---------+----+-----------+ 2| Member | Host | Role | State | TL | Lag in MB | 3+-------------------------------------+--------------+---------+---------+----+-----------+ 4| gitlab-database-1.example.com | 172.18.0.111 | Replica | stopped | | unknown | 5| gitlab-database-2.example.com | 172.18.0.112 | Replica | stopped | | unknown | 6| gitlab-database-3.example.com | 172.18.0.113 | Replica | stopped | | unknown | 7+-------------------------------------+--------------+---------+---------+----+-----------+
在删除 Consul 中的 Patroni 状态之前,尝试解决 Patroni 节点上的 gitlab-ctl 错误。
当第一个 Patroni 节点启动时,此过程会导致重新初始化的 Patroni 集群。
要重置 Consul 中的 Patroni 状态:
-
记下曾经是领导者的 Patroni 节点,或者应用程序认为是当前领导者的节点,如果当前状态显示多个或没有:
-
在 PgBouncer 节点的 /var/opt/gitlab/consul/databases.ini 中查看,它包含当前领导者的主机名。
-
在 所有 数据库节点上查看 Patroni 日志 /var/log/gitlab/patroni/current(或较旧的旋转和压缩日志 /var/log/gitlab/patroni/@40000*),看看哪个服务器最近被集群标识为领导者:
plaintextINFO: no action. I am a secondary (database1.local) and following a leader (database2.local)
-
-
停止所有节点上的 Patroni:
shellsudo gitlab-ctl stop patroni -
重置 Consul 中的状态:
shell/opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/ -
启动一个 Patroni 节点,它初始化 Patroni 集群以选举为领导者。强烈建议启动之前的领导者(在第一步中记录),以免丢失因集群状态损坏而未复制的现有写入:
shellsudo gitlab-ctl start patroni -
启动所有其他 Patroni 节点,以副本身份加入 Patroni 集群:
shellsudo gitlab-ctl start patroni
如果您仍然看到问题,下一步是恢复最后一个健康的备份。
Patroni 日志中关于 127.0.0.1 的 pg_hba.conf 条目错误
Patroni 日志中的以下日志条目表明复制未正常工作,需要进行配置更改:
plaintextFATAL: no pg_hba.conf entry for replication connection from host "127.0.0.1", user "gitlab_replicator"
要解决此问题,请确保回环接口包含在 CIDR 地址列表中:
-
编辑 /etc/gitlab/gitlab.rb:
rubypostgresql['trust_auth_cidr_addresses'] = %w(<other_cidrs> 127.0.0.1/32) -
重新配置极狐GitLab 以使更改生效。
错误:请求的起始点超前于写入日志 (WAL) 刷新位置
Patroni 日志中的此错误表示数据库未进行复制:
plaintextFATAL: 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 可能会启动失败,并记录错误和堆栈跟踪:
plaintext1MemoryError 2Traceback (most recent call last): 3 File "/opt/gitlab/embedded/bin/patroni", line 8, in <module> 4 sys.exit(main()) 5[..] 6 File "/opt/gitlab/embedded/lib/python3.7/ctypes/__init__.py", line 273, in _reset_cache 7 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 无法确定 它需要关于安装的信息,如果数据库服务器无法启动:
plaintextMalformed 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.
plaintextError 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) 应包含大量信息, 但可能仅创建:
json{ "name": "<HOSTNAME>" }
解决此问题的以下过程包括重新初始化此副本: 当前此节点上的 PostgreSQL 状态将被丢弃:
-
关闭 Patroni 和(如果存在)PostgreSQL 服务:
shellsudo gitlab-ctl status sudo gitlab-ctl stop patroni sudo gitlab-ctl stop postgresql -
删除 /var/opt/gitlab/postgresql/data,以防其状态阻止 PostgreSQL 启动:
shellcd /var/opt/gitlab/postgresql sudo rm -rf data小心此步骤以避免数据丢失。 此步骤也可以通过重命名 data/ 来实现: 确保有足够的磁盘空间来存储主数据库的新副本, 并在修复副本后删除额外目录。
-
在 PostgreSQL 未运行的情况下,节点文件现在可以成功创建:
shellsudo gitlab-ctl reconfigure -
启动 Patroni:
shellsudo gitlab-ctl start patroni -
监控日志并检查集群状态:
shellsudo gitlab-ctl tail patroni sudo gitlab-ctl patroni members -
再次运行 reconfigure:
shellsudo gitlab-ctl reconfigure -
如果 gitlab-ctl patroni members 指示需要,重新初始化副本:
shellsudo gitlab-ctl patroni reinitialize-replica
如果此过程不起作用并且集群无法选举领导者, 还有另一个修复,应仅作为最后手段使用。
PostgreSQL 主版本升级在 Patroni 副本上失败
Patroni 副本在 gitlab-ctl pg-upgrade 期间可能会陷入循环, 并且升级失败。
一个示例症状集如下:
-
定义了 postgresql 服务, 通常不应该出现在 Patroni 节点上。它存在是因为 gitlab-ctl pg-upgrade 添加它以创建一个新的空数据库:
plaintextrun: patroni: (pid 1972) 1919s; run: log: (pid 1971) 1919s down: postgresql: 1s, normally up, want up; run: log: (pid 1973) 1919s -
在 /var/log/gitlab/postgresql/current 中,PostgreSQL 生成 PANIC 日志条目, 因为 Patroni 正在删除 /var/opt/gitlab/postgresql/data 作为重新初始化副本的一部分:
plaintextDETAIL: 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 -
在 /var/log/gitlab/patroni/current 中,Patroni 记录以下内容。 本地 PostgreSQL 版本与集群领导者不同:
plaintextINFO: 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 的步骤失败。
此解决方法通过设置节点使用新的 PostgreSQL 版本完成 Patroni 副本上的 PostgreSQL 升级,然后将其重新初始化为领导者升级时创建的新集群中的副本:
-
检查所有节点上的集群状态以确认哪个是领导者 以及副本处于什么状态
shellsudo gitlab-ctl patroni members -
副本:检查哪个版本的 PostgreSQL 是活动的:
shellsudo ls -al /opt/gitlab/embedded/bin | grep postgres -
副本:确保节点文件正确并且 gitlab-ctl 可以运行。这解决了 如果副本也有任何这些错误,运行 gitlab-ctl 时的错误问题:
shellsudo gitlab-ctl stop patroni sudo gitlab-ctl reconfigure -
副本:重新链接 PostgreSQL 二进制文件到所需版本 以修复 incompatible server version 错误:
-
编辑 /etc/gitlab/gitlab.rb 并指定所需版本:
rubypostgresql['version'] = 13 -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
检查二进制文件是否已重新链接。分发的 PostgreSQL 二进制文件在主版本之间有所不同,通常会有少量不正确的符号链接:
shellsudo ls -al /opt/gitlab/embedded/bin | grep postgres
-
-
副本:确保 PostgreSQL 为指定版本完全重新初始化:
shellcd /var/opt/gitlab/postgresql sudo rm -rf data sudo gitlab-ctl reconfigure -
副本:可选地在两个额外的终端会话中监控数据库:
-
随着 pg_basebackup 的运行,磁盘使用量增加。跟踪副本初始化的进度:
shellcd /var/opt/gitlab/postgresql watch du -sh data -
在日志中监控过程:
shellsudo gitlab-ctl tail patroni
-
-
副本:启动 Patroni 以重新初始化副本:
shellsudo gitlab-ctl start patroni -
副本:完成后,从 /etc/gitlab/gitlab.rb 中删除硬编码版本:
-
编辑 /etc/gitlab/gitlab.rb 并删除 postgresql['version']。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
检查正确的二进制文件是否已链接:
shellsudo ls -al /opt/gitlab/embedded/bin | grep postgres
-
-
检查所有节点上的集群状态:
shellsudo gitlab-ctl patroni members
如果需要,请在其他副本上重复此过程。
其他组件的问题
如果您遇到未在此处概述的组件问题,请务必查看其特定文档页面的故障排除部分: