Linux 包安装的 PostgreSQL 复制和故障排除
- Tier: Premium, Ultimate
- Offering: GitLab Self-Managed
在使用 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.rb 中的 trust_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 以使更改生效。
Patroni 切换后 PgBouncer 节点未故障转移
由于影响 GitLab 16.5.0 之前版本的已知问题,在 Patroni 切换后,PgBouncer 节点的自动故障转移不会发生。在此示例中,GitLab 未能检测到暂停的数据库,然后尝试恢复一个未暂停的数据库:
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重新初始化副本
如果副本无法启动或重新加入集群,或者当它落后且无法赶上时,可能需要重新初始化副本:
-
检查复制状态 以确认需要重新初始化哪个服务器。例如:
+ 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 | | +-------------------------------------+--------------+---------+--------------+----+-----------+ -
登录到故障服务器并重新初始化数据库和复制。Patroni 会关闭该服务器上的 PostgreSQL,删除数据目录,并从头开始重新初始化:
sudo gitlab-ctl patroni reinitialize-replica --member gitlab-database-2.example.com这可以在任何 Patroni 节点上运行,但请注意,不带
--member的sudo gitlab-ctl patroni reinitialize-replica会重启它运行的服务器。 您应该在故障服务器上本地运行它以减少意外数据丢失的风险。 -
监控日志:
sudo gitlab-ctl tail patroni
重置 Consul 中的 Patroni 状态
重置 Consul 中的 Patroni 状态是一个可能具有破坏性的过程。请确保您首先有一个健康的数据库备份。
作为最后手段,您可以完全重置 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 状态:
-
记录下之前是主节点的 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)
-
-
在所有节点上停止 Patroni:
sudo gitlab-ctl stop patroni -
重置 Consul 中的状态:
/opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/ -
启动一个 Patroni 节点,它会初始化 Patroni 集群以选举主节点。 强烈建议启动之前的主节点(在第一步中记录的), 以避免丢失可能因集群状态损坏而未复制的现有写入:
sudo gitlab-ctl start patroni -
启动所有其他作为副本加入 Patroni 集群的 Patroni 节点:
sudo gitlab-ctl start patroni
如果您仍然遇到问题,下一步是恢复最后的健康备份。
Patroni 日志中关于 pg_hba.conf 条目为 127.0.0.1 的错误
Patroni 日志中的以下日志条目表明复制未正常工作,需要进行配置更改:
FATAL: no pg_hba.conf entry for replication connection from host "127.0.0.1", user "gitlab_replicator"要解决此问题,请确保回环接口包含在 CIDR 地址列表中:
-
编辑
/etc/gitlab/gitlab.rb:postgresql['trust_auth_cidr_addresses'] = %w(<other_cidrs> 127.0.0.1/32) -
重新配置 GitLab 以使更改生效。
错误:请求的起始点先于预写日志(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 的当前状态将被丢弃:
-
关闭 Patroni 和(如果存在)PostgreSQL 服务:
sudo gitlab-ctl status sudo gitlab-ctl stop patroni sudo gitlab-ctl stop postgresql -
删除
/var/opt/gitlab/postgresql/data以防其状态阻止 PostgreSQL 启动:cd /var/opt/gitlab/postgresql sudo rm -rf data请谨慎执行此步骤以避免数据丢失。 也可以通过重命名
data/来实现此步骤: 确保磁盘有足够空间用于主数据库的新副本, 并在修复副本后删除额外目录。 -
在 PostgreSQL 未运行的情况下,节点文件现在可以成功创建:
sudo gitlab-ctl reconfigure -
启动 Patroni:
sudo gitlab-ctl start patroni -
监控日志并检查集群状态:
sudo gitlab-ctl tail patroni sudo gitlab-ctl patroni members -
再次运行
reconfigure:sudo gitlab-ctl reconfigure -
如果
gitlab-ctl patroni members表明需要,则重新初始化副本:sudo gitlab-ctl patroni reinitialize-replica
如果此程序不起作用且集群无法选举主节点, 还有另一种修复方法,这应该只 作为最后手段使用。
Patroni 副本上的 PostgreSQL 主版本升级失败
在 gitlab-ctl pg-upgrade 期间,Patroni 副本可能会陷入循环,升级失败。
一组症状示例如下:
-
定义了一个
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 -
Patroni 在重新初始化副本时删除
/var/opt/gitlab/postgresql/data,PostgreSQL 在/var/log/gitlab/postgresql/current中生成PANIC日志条目: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 -
在
/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 的步骤失败。
此解决方法通过将节点设置为使用新的 PostgreSQL 版本, 然后在升级主节点时创建的新集群中重新初始化 它来完成 Patroni 副本上的 PostgreSQL 升级:
-
在所有节点上检查集群状态,确认哪个是主节点 以及副本的状态
sudo gitlab-ctl patroni members -
副本:检查哪个版本的 PostgreSQL 处于活动状态:
sudo ls -al /opt/gitlab/embedded/bin | grep postgres -
副本:确保节点文件正确且
gitlab-ctl可以运行。这会解决 如果副本也有任何运行gitlab-ctl的错误问题:sudo gitlab-ctl stop patroni sudo gitlab-ctl reconfigure -
副本:重新链接 PostgreSQL 二进制文件到所需版本 以修复
incompatible server version错误:-
编辑
/etc/gitlab/gitlab.rb并指定所需版本:postgresql['version'] = 13 -
重新配置 GitLab:
sudo gitlab-ctl reconfigure -
检查二进制文件是否已重新链接。为 PostgreSQL 分发的二进制文件在主版本之间有所不同, 通常会有少量错误的符号链接:
sudo ls -al /opt/gitlab/embedded/bin | grep postgres
-
-
副本:确保 PostgreSQL 为指定版本完全重新初始化:
cd /var/opt/gitlab/postgresql sudo rm -rf data sudo gitlab-ctl reconfigure -
副本:可选地在另外两个终端会话中监控数据库:
-
磁盘使用量随
pg_basebackup运行而增加。使用以下命令跟踪 副本初始化进度:cd /var/opt/gitlab/postgresql watch du -sh data -
在日志中监控进程:
sudo gitlab-ctl tail patroni
-
-
副本:启动 Patroni 以重新初始化副本:
sudo gitlab-ctl start patroni -
副本:完成后,从
/etc/gitlab/gitlab.rb中删除硬编码版本:-
编辑
/etc/gitlab/gitlab.rb并删除postgresql['version']。 -
重新配置 GitLab:
sudo gitlab-ctl reconfigure -
检查正确的二进制文件已链接:
sudo ls -al /opt/gitlab/embedded/bin | grep postgres
-
-
在所有节点上检查集群状态:
sudo gitlab-ctl patroni members
如果需要,对其他副本重复此过程。
创建 PostgreSQL 副本时陷入循环
如果 PostgreSQL 副本似乎迁移但然后循环重启,请检查
副本和主服务器上的 /opt/gitlab-data/postgresql/ 文件夹权限。
您还可以在日志中看到此错误消息:
could not get COPY data stream: ERROR: could not open file "<file>" Permission denied。
其他组件的问题
如果您遇到本文档未概述的组件问题,请务必检查其特定文档页面的故障排除部分: