Gitaly Cluster (Praefect) 恢复选项和工具
Gitaly Cluster (Praefect) 可以从主节点故障和不可用的仓库中恢复。Gitaly Cluster (Praefect) 可以执行数据恢复,并拥有 Praefect 跟踪数据库工具。
管理 Gitaly Cluster (Praefect) 上的 Gitaly 节点
您可以在 Gitaly Cluster (Praefect) 上添加和替换 Gitaly 节点。
添加新的 Gitaly 节点
要添加新的 Gitaly 节点:
-
按照文档安装新的 Gitaly 节点。
-
在
praefect['virtual_storages']下的Praefect 配置中添加新节点。 -
通过运行以下命令重新配置并重启 Praefect:
gitlab-ctl reconfigure gitlab-ctl restart praefect
复制行为取决于您的复制因子设置。
自定义复制因子
如果设置了自定义复制因子,Praefect 不会自动将现有仓库复制到新的 Gitaly 节点。您必须使用 set-replication-factor Praefect 命令为每个仓库设置复制因子。新仓库将根据复制因子进行复制。
默认复制因子
如果使用默认复制因子,Praefect 会自动将所有数据复制到添加到配置中的任何新 Gitaly 节点,以维持复制因子。
替换现有的 Gitaly 节点
您可以用具有相同名称或不同名称的新节点替换现有的 Gitaly 节点。在移除旧节点之前:
- 如果设置了复制因子,它必须大于 1 以防止数据丢失。
- 如果没有设置复制因子,仓库将在虚拟存储下的每个节点上复制。
当移除主 Gitaly 节点时,由该节点管理的仓库将变得不可用,直到:
- 节点被替换并完成复制。
- 包含被替换主节点数据的新替换节点变得可用。
在节点不可用期间,对受影响仓库的读取请求会因 404 错误而失败。Gitaly 会在下一次对受影响仓库的写入尝试时自动解决此情况,通过触发故障转移来建立新的主节点。
使用相同名称的节点
要为替换节点使用相同的名称,请使用仓库验证器扫描存储并删除悬空的元数据记录。手动优先验证被替换的存储以加快处理速度。
使用不同名称的节点
替换 Gitaly Cluster (Praefect) 中具有不同名称节点的步骤取决于是否设置了复制因子。
如果设置了自定义复制因子,请使用 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 节点的名称进行更新。
如果设置了默认复制因子,新节点不会 自动包含在复制中。您必须按照前面描述的步骤操作。
在您验证仓库已成功复制到新节点后:
-
从
praefect['virtual_storages']下的Praefect 配置中移除gitaly-1节点。 -
重新配置并重启 Praefect:
gitlab-ctl reconfigure gitlab-ctl restart praefect
可以忽略引用旧 Gitaly 节点的数据库状态。
另一种方法是在配置新的 Gitaly 节点后,将所有仓库从旧存储重新分配到新存储:
-
连接到 Praefect 数据库:
/opt/gitlab/embedded/bin/psql -h <psql host> -U <user> -d <database name> -
更新
repository_assignments表,用新的 Gitaly 节点名称(例如,new-gitaly)替换旧的 Gitaly 节点名称 (例如,old-gitaly):UPDATE repository_assignments SET storage='new-gitaly' WHERE storage='old-gitaly';
这将触发适当的复制作业,使系统恢复到期望状态。
主节点故障
Gitaly Cluster (Praefect) 通过将健康的次要节点提升为新的主节点来从故障的主 Gitaly 节点中恢复。 Gitaly Cluster (Praefect):
- 选择一个具有仓库完全最新副本的健康次要节点作为新的主节点。
- 如果没有完全最新的次要节点可用,则选择与主节点相比未复制写入最少的次要节点作为新的主节点。
- 如果在健康的次要节点上没有仓库的完全最新副本,则仓库将变得不可用。使用Praefect
dataloss子命令来检测它。
不可用的仓库
如果仓库的所有最新副本都不可用,则该仓库不可用。不可用的仓库无法通过 Praefect 访问,以防止提供可能破坏自动化工具的陈旧数据。
检查数据丢失
Praefect dataloss 子命令识别不可用的仓库。这有助于识别潜在的数据丢失
以及由于所有最新副本副本都不可用而无法访问的仓库。
以下参数可用:
-virtual-storage指定要检查的虚拟存储。因为它们可能需要 管理员干预,默认行为是显示不可用的仓库。-partially-unavailable指定是否在输出中包含可用但某些分配副本不可用的仓库。
dataloss 仍处于 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。 - 同步存储列出了已复制最新成功写入及之前的所有写入的副本。
- 过时存储列出了包含仓库过时副本的副本。没有仓库副本但应包含仓库的副本也在此列出。副本缺失的最大更改数 列在副本旁边。重要的是要注意,过时的副本可能完全是最新的或包含 更晚的更改,但 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 节点上运行 replicas Rake 任务。
接受数据丢失
accept-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>启用写入或接受数据丢失
accept-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:
-
将仓库的选定副本标记为最新版本。
-
将副本复制到其他分配的 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', # 禁用该功能
},
}手动移除仓库
remove-repository Praefect 子命令从 Gitaly Cluster (Praefect) 中移除仓库,以及与给定仓库关联的所有状态,包括:
- 所有相关 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>替换为要移除的仓库的相对路径。 -
添加
-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', }, ], }在此示例中,要指定的虚拟存储是
default或storage-1。 -
-repository是仓库在存储中的相对路径以@hashed开头。 例如:@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git
运行 remove-repository 后,仓库的部分内容可能继续存在。这可能是因为:
- 删除错误。
- 针对仓库的进行中 RPC 调用。
如果发生这种情况,请再次运行 remove-repository。
Praefect 跟踪数据库维护
本节记录了 Praefect 跟踪数据库的常见维护任务。
列出未跟踪的仓库
list-untracked-repositories Praefect 子命令列出 Gitaly Cluster (Praefect) 中满足以下两个条件的仓库:
- 至少存在于一个 Gitaly 存储中。
- 未在 Praefect 跟踪数据库中跟踪。
添加 -older-than 选项以避免显示以下仓库:
- 正在创建过程中的仓库。
- Praefect 跟踪数据库中尚不存在的记录的仓库。
将 <duration> 替换为时间持续时间(例如,5s、10m 或 1h)。默认为 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"}手动将单个仓库添加到跟踪数据库
由于已知问题,您无法将具有 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', }, ], }在此示例中,要指定的虚拟存储是
default或storage-1。 -
-relative-path是虚拟存储中的相对路径。通常以@hashed开头。 例如:@hashed/f5/ca/f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b.git -
-replica-path是物理存储上的相对路径。可以以@cluster开头或匹配relative_path。 -
-authoritative-storage是我们希望 Praefect 视为主节点的存储。如果 按仓库复制设置为复制策略,则为必需。 -
-replicate-immediately使命令立即将仓库复制到其次要节点。 否则,复制作业将安排在数据库中执行,并由 Praefect 后台进程拾取。
该命令输出:
- 结果到
STDOUT和命令的日志。 - 错误到
STDERR。
如果满足以下条件,此命令将失败:
- 仓库已被 Praefect 跟踪数据库跟踪。
- 仓库在磁盘上不存在。
手动将多个仓库添加到跟踪数据库
由于已知问题,您无法将具有 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 后台进程拾取。
列出虚拟存储详细信息
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。