Gitaly 集群恢复选项和工具

极狐GitLab 集群可以从主节点故障和不可用的软件包中恢复。极狐GitLab 集群可以执行数据恢复,并拥有 Praefect 跟踪数据库工具。

在极狐GitLab 集群上管理 Gitaly 节点

您可以在极狐GitLab 集群中添加和替换 Gitaly 节点。

添加新的 Gitaly 节点

要添加新的 Gitaly 节点:

  1. 按照文档安装新的 Gitaly 节点。
  2. praefect['virtual_storages'] 下将新节点添加到您的 Praefect 配置
  3. 运行以下命令以重新配置并重启 Praefect:

    gitlab-ctl reconfigure
    gitlab-ctl restart praefect
    

复制行为取决于您的复制因子设置。

自定义复制因子

如果设置了自定义复制因子,Praefect 不会自动复制现有软件包到新的 Gitaly 节点。您必须使用 set-replication-factor Praefect 命令为每个软件包设置复制因子。新的软件包会根据复制因子进行复制。

默认复制因子

如果使用默认复制因子,Praefect 会自动将所有数据复制到添加到配置中的任何新的 Gitaly 节点,以维护复制因子。

替换现有的 Gitaly 节点

您可以用相同名称或不同名称的节点替换现有的 Gitaly 节点。在移除旧节点之前:

  • 如果设置了复制因子,它必须大于 1,以防止数据丢失。
  • 如果没有设置复制因子,软件包会在虚拟存储下的每个节点上复制。

使用具有相同名称的节点

要为替换节点使用相同名称,请使用软件包验证器扫描存储并移除悬空的元数据记录。手动优先验证替换存储以加快过程。

使用具有不同名称的节点

使用不同名称为极狐GitLab 集群的替换节点的步骤取决于是否设置了复制因子

设置复制因子

如果设置了自定义复制因子,请使用 praefect set-replication-factor 再次为每个软件包设置复制因子,以获得新的存储分配。

例如,如果虚拟存储中的两个节点的复制因子为 2,并且添加了一个新的节点(gitaly-3),您应该将复制因子增加到 3:

$ sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -relative-path @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 3

current assignments: gitaly-1, gitaly-2, gitaly-3

这确保软件包被复制到新的节点,并且 repository_assignments 表格会更新新的 Gitaly 节点名称。

如果设置了默认复制因子,则不会自动包括新的节点进行复制。您必须遵循上面描述的步骤。

在您验证软件包成功复制到新节点后:

  1. praefect['virtual_storages'] 下的 Praefect 配置中移除 gitaly-1 节点。
  2. 重新配置并重启 Praefect:

    gitlab-ctl reconfigure
    gitlab-ctl restart praefect
    

可以忽略指向旧 Gitaly 节点的数据库状态。

另一种方法是,在配置新的 Gitaly 节点后,将所有软件包从旧存储重新分配到新的存储:

  1. 连接到 Praefect 数据库:

    /opt/gitlab/embedded/bin/psql -h <psql host> -U <user> -d <database name>
    
  2. 更新 repository_assignments 表格,将旧 Gitaly 节点名称(例如,old-gitaly)替换为新 Gitaly 节点名称(例如,new-gitaly):

    UPDATE repository_assignments SET storage='new-gitaly' WHERE storage='old-gitaly';
    

这将触发适当的复制任务以使系统恢复到所需状态。

主节点故障

极狐GitLab 集群通过将健康的次级提升为新的主节点来恢复失败的主 Gitaly 节点。极狐GitLab 集群:

  • 选择一个具有完全最新软件包副本的健康次级作为新的主节点。
  • 如果没有完全最新的次级可用,选择具有最少未复制写入的次级作为新的主节点。
  • 如果健康的次级上没有完全最新的软件包副本,软件包将变得不可用。使用 Praefect dataloss 子命令来检测它。

不可用的软件包

如果所有最新的副本都不可用,则软件包不可用。不可用的软件包无法通过 Praefect 访问,以防止提供可能破坏自动工具的陈旧数据。

检查数据丢失

Praefect dataloss 子命令识别不可用的软件包。这有助于识别潜在的数据丢失以及因为所有最新副本不可用而不再可访问的软件包。

可用的参数包括:

  • -virtual-storage 指定要检查哪个虚拟存储。由于可能需要管理员干预,默认行为是显示不可用的软件包。
  • -partially-unavailable 指定是否在输出中包含可用但有一些分配副本不可用的软件包。
notedataloss 仍处于 beta 阶段,输出格式可能会发生变化。

要检查具有过时主节点或不可用的软件包,请运行:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss [-virtual-storage <virtual-storage>]

如果未指定任何配置的虚拟存储,则会检查:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss

输出中列出了没有健康且完全最新副本可用的软件包。每个软件包打印以下信息:

  • 软件包存储目录的相对路径标识每个软件包并分组相关信息。
  • 如果软件包不可用,则在磁盘路径旁边打印 (unavailable)
  • 主字段列出软件包的当前主节点。如果软件包没有主节点,则字段显示 No Primary
  • In-Sync Storages 列出已复制最新成功写入及其之前所有写入的副本。
  • Outdated Storages 列出包含软件包过时副本的副本。没有软件包副本但应该包含它的副本也在此列出。副本缺少的最大更改数列在副本旁边。注意过时的副本可能是完全最新或包含更晚的更改,但 Praefect 无法保证。

其他信息包括:

  • 是否分配节点来托管软件包与每个节点的状态一起列出。 assigned host 打印在分配存储软件包的节点旁边。如果节点包含软件包副本但未分配存储软件包,则文本会被省略。这些副本不会被 Praefect 保持同步,但可能充当复制源以使分配的副本最新。
  • unhealthy 打印在位于不健康 Gitaly 节点上的副本旁边。

示例输出:

Virtual storage: default
  Outdated repositories:
    @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git (unavailable):
      Primary: gitaly-1
      In-Sync Storages:
        gitaly-2, assigned host, unhealthy
      Outdated Storages:
        gitaly-1 is behind by 3 changes or less, assigned host
        gitaly-3 is behind by 3 changes or less

当每个软件包可用时会打印确认。例如:

Virtual storage: default
  All repositories are available!

可用软件包的不可用副本

要列出可用但在某些分配节点不可用的软件包信息,请使用 -partially-unavailable 标志。

如果有健康的最新副本可用,则软件包是可用的。一些分配的次级副本可能暂时不可访问,因为它们正在等待复制最新的更改。

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss [-virtual-storage <virtual-storage>] [-partially-unavailable]

示例输出:

Virtual storage: default
  Outdated repositories:
    @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git:
      Primary: gitaly-1
      In-Sync Storages:
        gitaly-1, assigned host
      Outdated Storages:
        gitaly-2 is behind by 3 changes or less, assigned host
        gitaly-3 is behind by 3 changes or less

设置 -partially-unavailable 标志后,如果每个分配副本完全最新且健康,则会打印确认。

例如:

Virtual storage: default
  All repositories are fully available on all assigned storages!

检查软件包校验和

要检查项目的软件包在所有 Gitaly 节点上的校验和,请在主极狐GitLab 节点上运行副本 Rake 任务

接受数据丢失

cautionaccept-dataloss 会导致永久性数据丢失,覆盖软件包的其他版本。在使用之前必须进行数据恢复工作

如果无法使其中一个最新副本重新上线,您可能需要接受数据丢失。在接受数据丢失时,Praefect 将选择的软件包副本标记为最新版本,并将其复制到其他分配的 Gitaly 节点。此过程会覆盖软件包的任何其他版本,因此必须谨慎操作。

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml accept-dataloss -virtual-storage <virtual-storage> -relative-path <relative-path> -authoritative-storage <storage-name>

启用写入或接受数据丢失

cautionaccept-dataloss 会导致永久性数据丢失,覆盖软件包的其他版本。在使用之前必须进行数据恢复工作

Praefect 提供以下子命令以重新启用写入或接受数据丢失。如果无法使其中一个最新节点重新上线,您可能需要接受数据丢失:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml accept-dataloss -virtual-storage <virtual-storage> -relative-path <relative-path> -authoritative-storage <storage-name>

在接受数据丢失时,Praefect:

  1. 将选择的软件包副本标记为最新版本。
  2. 将副本复制到其他分配的 Gitaly 节点。

    此过程会覆盖软件包的任何其他副本,因此必须谨慎操作。

数据恢复

如果 Gitaly 节点由于任何原因失败复制任务,它最终会托管受影响软件包的过时版本。Praefect 提供用于自动协调的工具。这些工具协调过时的软件包以使其再次完全最新。

Praefect 自动协调未最新的软件包。默认情况下,每五分钟进行一次。对于健康 Gitaly 节点上的每个过时软件包,Praefect 从另一个健康 Gitaly 节点上的随机、完全最新的软件包副本中选择复制源。仅当目标软件包没有其他复制任务挂起时,才会安排复制任务。

可以通过配置更改协调频率。值可以是任何有效的Go 持续时间值。值低于 0 禁用该功能。

示例:

praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '5m', # 默认值
   },
}
praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '30s', # 每 30 秒协调一次
   },
}
praefect['configuration'] = {
   # ...
   reconciliation: {
      # ...
      scheduling_interval: '0', # 禁用该功能
   },
}

手动移除软件包

  • 在极狐GitLab 15.3 中引入,支持从 Praefect 跟踪数据库中移除软件包。

remove-repository Praefect 子命令移除极狐GitLab 集群中的软件包,以及与给定软件包相关的所有状态,包括:

  • 所有相关 Gitaly 节点上的磁盘软件包。
  • Praefect 跟踪的任何数据库状态。

默认情况下,该命令在干运行模式下操作。例如:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -relative-path <repository>
  • <virtual-storage> 替换为包含软件包的虚拟存储名称。
  • <repository> 替换为要移除的软件包的相对路径。
  • 在极狐GitLab 15.3 及更高版本中,添加 -db-only 以移除 Praefect 跟踪数据库条目而不移除磁盘软件包。使用此选项可移除孤立的数据库条目,并在不小心指定有效软件包时保护磁盘软件包数据免于删除。如果不小心删除了数据库条目,请使用 track-repository 命令重新跟踪软件包。
  • 添加 -apply 以在干运行模式之外运行命令并移除软件包。例如:

    sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml remove-repository -virtual-storage <virtual-storage> -relative-path <repository> -apply
    
  • -virtual-storage 是软件包所在的虚拟存储。虚拟存储在 /etc/gitlab/gitlab.rb 中配置为 praefect['configuration']['virtual_storage],如下所示:

    praefect['configuration'] = {
      # ...
      virtual_storage: [
        {
          # ...
          name: 'default',
        },
        {
          # ...
          name: 'storage-1',
        },
      ],
    }
    

    在此示例中,要指定的虚拟存储是 defaultstorage-1

  • -repository 是存储中的软件包的相对路径@hashed 开头。 例如:

    @hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
    

在运行 remove-repository 后,软件包的部分可能会继续存在。这可能是因为:

  • 删除错误。
  • 针对软件包的飞行中的 RPC 调用。

如果发生这种情况,请再次运行 remove-repository

Praefect 跟踪数据库维护

此部分记录了 Praefect 跟踪数据库上的常见维护任务。

列出未跟踪的软件包

  • 在极狐GitLab 15.0 中添加 older-than 选项。

list-untracked-repositories Praefect 子命令列出极狐GitLab 集群中至少:

  • 存在于一个 Gitaly 存储中。
  • 未在 Praefect 跟踪数据库中跟踪的软件包。

添加 -older-than 选项以避免显示:

  • 正在创建过程中的软件包。
  • Praefect 跟踪数据库中尚不存在记录的软件包。

<duration> 替换为时间持续时间(例如,5s10m1h)。默认为 6h

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-untracked-repositories -older-than <duration>

仅考虑在指定持续时间之前创建的软件包。

命令输出:

  • 结果到 STDOUT 和命令的日志。
  • 错误到 STDERR

每个条目是一个完整的 JSON 字符串,末尾有一个换行符(可使用 -delimiter 标志配置)。例如:

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-untracked-repositories
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567890.git"}
{"virtual_storage":"default","storage":"gitaly-1","relative_path":"@hashed/ab/cd/abcd123456789012345678901234567890123456789012345678901234567891.git"}

手动添加单个软件包到跟踪数据库

caution由于已知问题,您无法使用 Praefect 生成的副本路径(@cluster)将软件包添加到 Praefect 跟踪数据库。这些软件包与极狐GitLab 使用的软件包路径不相关且无法访问。

track-repository Praefect 子命令将磁盘上的软件包添加到 Praefect 跟踪数据库以进行跟踪。

sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage <virtual-storage> -authoritative-storage <storage-name> -relative-path <repository> -replica-path <disk_path> -replicate-immediately
  • -virtual-storage 是软件包所在的虚拟存储。虚拟存储在 /etc/gitlab/gitlab.rb 中配置为 praefect['configuration'][:virtual_storage],如下所示:

    praefect['configuration'] = {
      # ...
      virtual_storage: [
        {
          # ...
          name: 'default',
        },
        {
          # ...
          name: 'storage-1',
        },
      ],
    }
    

    在此示例中,要指定的虚拟存储是 defaultstorage-1

  • -relative-path 是虚拟存储中的相对路径。通常@hashed 开头。 例如:

    @hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
    
  • -replica-path 是物理存储上的相对路径。可以以 @cluster 或匹配 relative_path 开头。
  • -authoritative-storage 是我们希望 Praefect 视为主存储的存储。如果设置了每软件包复制作为复制策略,则为必需。
  • -replicate-immediately 导致命令立即将软件包复制到其次级。否则,复制任务会在数据库中安排执行,并由 Praefect 后台进程拾取。

命令输出:

  • 结果到 STDOUT 和命令的日志。
  • 错误到 STDERR

如果出现以下情况,则命令失败:

  • 软件包已被 Praefect 跟踪数据库跟踪。
  • 软件包在磁盘上不存在。

手动添加多个软件包到跟踪数据库

  • 在极狐GitLab 15.4 中引入。
caution由于已知问题,您无法使用 Praefect 生成的副本路径(@cluster)将软件包添加到 Praefect 跟踪数据库。这些软件包与极狐GitLab 使用的软件包路径不相关且无法访问。

使用 API 进行的迁移会自动将软件包添加到 Praefect 跟踪数据库。

如果您是手动从现有基础设施复制软件包,可以使用 track-repositories Praefect 子命令。此子命令添加大量磁盘上的软件包到 Praefect 跟踪数据库。

# Omnibus 极狐GitLab 安装
sudo gitlab-ctl praefect track-repositories --input-path /path/to/input.json

# 源安装
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repositories -input-path /path/to/input.json

命令验证所有条目:

  • 格式正确并包含必需字段。
  • 对应磁盘上的有效 Git 软件包。
  • 未在 Praefect 跟踪数据库中跟踪。

如果任何条目未通过这些检查,则命令在尝试跟踪软件包之前中止。

  • input-path 是包含格式为换行分隔 JSON 对象的软件包列表的文件路径。对象必须包含以下键:
    • relative_path: 对应于 track-repository中的 repository
    • authoritative-storage: Praefect 要视为主存储的存储。
    • virtual-storage: 软件包所在的虚拟存储。

      例如:

      {"relative_path":"@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git","replica_path":"@cluster/fe/d3/1","authoritative_storage":"gitaly-1","virtual_storage":"default"}
      {"relative_path":"@hashed/f8/9f/f89f8d0e735a91c5269ab08d72fa27670d000e7561698d6e664e7b603f5c4e40.git","replica_path":"@cluster/7b/28/2","authoritative_storage":"gitaly-2","virtual_storage":"default"}
      
  • -replicate-immediately, 导致命令立即将软件包复制到其次级。否则,复制任务会在数据库中安排执行,并由 Praefect 后台进程拾取。

列出虚拟存储详细信息

  • 在极狐GitLab 15.1 中引入。

list-storages Praefect 子命令列出虚拟存储及其关联的存储节点。如果虚拟存储:

  • 使用 -virtual-storage 指定,它仅列出指定虚拟存储的存储节点。
  • 未指定,所有虚拟存储及其关联存储节点以表格格式列出。
sudo -u git -- /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml list-storages -virtual-storage <virtual_storage_name>

命令输出:

  • 结果到 STDOUT 和命令的日志。
  • 错误到 STDERR