Help us learn about your current experience with the documentation. Take the survey.

Geo PostgreSQL 复制故障排除

  • Tier: Premium, Ultimate
  • Offering: GitLab Self-Managed

以下各节概述了用于修复复制错误消息的故障排除步骤(在 geo:check 输出中显示为 Database replication working? ... no)。 此处提供的说明主要假设为单节点 Geo Linux 包部署,可能需要根据不同环境进行调整。

移除不活跃的复制槽

当连接到复制槽的复制客户端(一个辅助站点)断开连接时,该复制槽会被标记为“不活跃”。 不活跃的复制槽会导致 WAL 文件被保留,因为当客户端重新连接并且复制槽再次变为活跃时,这些文件需要被发送给客户端。 如果辅助站点无法重新连接,请使用以下步骤移除其对应的不活跃复制槽:

  1. 在 Geo 主站点的数据库节点上启动 PostgreSQL 控制台会话

    sudo gitlab-psql -d gitlabhq_production

    使用 gitlab-rails dbconsole 无效,因为管理复制槽需要超级用户权限。

  2. 查看复制槽,如果它们不活跃,则将其移除:

    SELECT * FROM pg_replication_slots;

    active 字段为 f 的槽是不活跃的。

  • 如果此槽本应是活跃的,因为你有一个使用该槽配置的辅助站点

    • 查看辅助站点PostgreSQL 日志,以了解复制未运行的原因。

    • 如果辅助站点无法再重新连接:

      1. 使用 PostgreSQL 控制台会话移除该槽:

        SELECT pg_drop_replication_slot('<name_of_inactive_slot>');
      2. 重新启动复制过程,这将正确地重新创建复制槽。

  • 如果你不再使用该槽(例如,你已不再启用 Geo),请按照移除该 Geo 站点的步骤操作。

消息:WARNING: oldest xmin is far in the pastpg_wal 大小持续增长

如果复制槽不活跃,则与该槽对应的 pg_wal 日志将被永久保留(或直到该槽再次变为活跃)。 这会导致磁盘使用量持续增长,并且以下消息会反复出现在 PostgreSQL 日志中:

WARNING: oldest xmin is far in the past
HINT: Close open transactions soon to avoid wraparound problems.
You might also need to commit or roll back old prepared transactions, or drop stale replication slots.

要解决此问题,你应该移除不活跃的复制槽并重新启动复制。

消息:ERROR: replication slots can only be used if max_replication_slots > 0

这意味着需要在数据库上设置 max_replication_slots PostgreSQL 变量。 此设置的默认值为 1。如果你有更多的辅助站点,可能需要增加此值。

请务必重启 PostgreSQL 以使此更改生效。更多详情请参阅 PostgreSQL 复制设置指南

消息:replication slot "geo_secondary_my_domain_com" does not exist

当 PostgreSQL 没有为该名称的辅助站点配置复制槽时,会发生此错误:

FATAL:  could not start WAL streaming: ERROR:  replication slot "geo_secondary_my_domain_com" does not exist

你可能需要在辅助站点上重新运行复制过程

消息:设置复制时出现 “Command exceeded allowed execution time”?

这可能在辅助站点启动复制过程时发生,表明你的初始数据集太大,无法在默认超时时间(30 分钟)内完成复制。 重新运行 gitlab-ctl replicate-geo-database,但为 --backup-timeout 指定一个更大的值:

sudo gitlab-ctl \
   replicate-geo-database \
   --host=<primary_node_hostname> \
   --slot-name=<secondary_slot_name> \
   --backup-timeout=21600

这会使初始复制有长达六小时的完成时间,而不是默认的 30 分钟。请根据你的安装需求进行调整。

消息:“PANIC: could not write to file pg_xlog/xlogtemp.123: No space left on device”

检查数据库中是否有任何未使用的复制槽。这可能导致大量日志数据在 pg_xlog 中累积。 移除不活跃的槽可以减少 pg_xlog 中使用的空间量。

消息:“ERROR: canceling statement due to conflict with recovery”

在典型使用情况下,此错误消息不常出现,并且系统具有足够的弹性可以自行恢复。 然而,在某些条件下,辅助站点上的一些数据库查询可能会运行过长,从而增加此错误消息的出现频率。 这可能导致某些查询因在每次复制时被取消而永远无法完成。

这些长时间运行的查询计划在未来被移除,但作为一种临时解决方案,我们建议启用 hot_standby_feedback。 这会增加站点上数据膨胀的可能性,因为它会阻止 VACUUM 清理最近死亡的行。 然而,此方法已在 GitLab.com 的生产环境中成功使用。

要启用 hot_standby_feedback,请在辅助站点/etc/gitlab/gitlab.rb 文件中添加以下内容:

postgresql['hot_standby_feedback'] = 'on'

然后重新配置 GitLab:

sudo gitlab-ctl reconfigure

为帮助我们解决此问题,请考虑在该议题上发表评论。

消息:server certificate for "PostgreSQL" does not match host name

如果你看到此错误:

FATAL:  could not connect to the primary server: server certificate for "PostgreSQL" does not match host name

发生此错误的原因是,Linux 包自动创建的 PostgreSQL 证书包含通用名称 (Common Name) PostgreSQL,但复制连接的是不同的主机,并且 GitLab 默认尝试使用 verify-full SSL 模式。 要解决此问题,你可以选择以下任一方法:

  • replicate-geo-database 命令中使用 --sslmode=verify-ca 参数。
  • 对于已复制的数据库,在 /var/opt/gitlab/postgresql/data/gitlab-geo.conf 中将 sslmode=verify-full 更改为 sslmode=verify-ca,然后运行 gitlab-ctl restart postgresql
  • 为 PostgreSQL 配置 SSL,使用自定义证书(在 CN 或 SAN 中包含用于连接数据库的主机名),而不是使用自动生成的证书。

消息:LOG: invalid CIDR mask in address

postgresql['md5_auth_cidr_addresses'] 中的地址格式不正确时,会发生此情况。

2020-03-20_23:59:57.60499 LOG:  invalid CIDR mask in address "***"
2020-03-20_23:59:57.60501 CONTEXT:  line 74 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

要解决此问题,请更新 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses'] 下的 IP 地址,使其符合 CIDR 格式(例如,10.0.0.1/32)。

消息:LOG: invalid IP mask "md5": Name or service not known

当你在 postgresql['md5_auth_cidr_addresses'] 中添加了不带子网掩码的 IP 地址时,会发生此情况。

2020-03-21_00:23:01.97353 LOG:  invalid IP mask "md5": Name or service not known
2020-03-21_00:23:01.97354 CONTEXT:  line 75 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

要解决此问题,请在 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses'] 下为 IP 地址添加子网掩码,使其符合 CIDR 格式(例如,10.0.0.1/32)。

消息:Found data in the gitlabhq_production database

如果在运行 gitlab-ctl replicate-geo-database 时收到错误 Found data in the gitlabhq_production database!,则表示在 projects 表中检测到了数据。 当检测到一个或多个项目时,操作会中止以防止意外数据丢失。要绕过此消息,请向命令传递 --force 选项。

消息:FATAL: could not map anonymous shared memory: Cannot allocate memory

如果你看到此消息,这意味着辅助站点的 PostgreSQL 试图请求超过可用内存的内存。有一个议题正在追踪此问题。

Patroni 日志中的错误消息示例(对于 Linux 包安装,日志位于 /var/log/gitlab/patroni/current):

2023-11-21_23:55:18.63727 FATAL:  could not map anonymous shared memory: Cannot allocate memory
2023-11-21_23:55:18.63729 HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 17035526144 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

临时解决方案是增加辅助站点 PostgreSQL 节点的可用内存,使其与主站点 PostgreSQL 节点的内存要求相匹配。

调查数据库复制延迟的原因

如果 sudo gitlab-rake geo:status 的输出显示 Database replication lag(数据库复制延迟)长时间保持较高水平,可以检查数据库复制中的主节点,以确定复制过程不同部分的延迟状态。 这些值分别称为 write_lagflush_lagreplay_lag。更多信息,请参阅 PostgreSQL 官方文档

在 Geo 主节点的数据库上运行以下命令以获取相关输出:

gitlab-psql -xc 'SELECT write_lag,flush_lag,replay_lag FROM pg_stat_replication;'

-[ RECORD 1 ]---------------
write_lag  | 00:00:00.072392
flush_lag  | 00:00:00.108168
replay_lag | 00:00:00.108283

如果其中一个或多个值显著偏高,这可能表明存在问题,应进行进一步调查。在确定原因时,请考虑以下几点:

  • write_lag 表示自主节点发送 WAL 字节、辅助节点接收这些字节,但尚未刷新或应用以来所经过的时间。
  • 较高的 write_lag 值可能表示主节点和辅助节点之间的网络性能下降或网速不足。
  • 较高的 flush_lag 值可能表示辅助节点存储设备的磁盘 I/O 性能下降或未达到最佳状态。
  • 较高的 replay_lag 值可能表示 PostgreSQL 中存在长时间运行的事务,或者 CPU 等必要资源已饱和。
  • write_lagflush_lag 之间的时间差表明 WAL 字节已发送到底层存储系统,但系统尚未报告它们已被刷新。 这些数据很可能尚未完全写入持久性存储,而是保存在某种易失性写入缓存中。
  • flush_lagreplay_lag 之间的差异表示已成功持久化到存储的 WAL 字节,但数据库系统无法重放它们。

卡在 Message: pg_basebackup: initiating base backup, waiting for checkpoint to complete

如果初始复制卡在 Message: pg_basebackup: initiating base backup, waiting for checkpoint to complete,这意味着 Geo 主站点未被积极使用。 这通常发生在非生产环境的 GitLab 服务器或全新的 GitLab 安装上。 临时解决方案是触发一些数据库写入操作。例如,你可以登录主站点并创建一些议题和评论。 另一种临时解决方案是在主站点的数据库上运行 SQL 查询 CHECKPOINT;

sudo gitlab-psql -xc 'CHECKPOINT;'