Geo 同步和验证错误故障排查

  • Tier: 专业版, 旗舰版
  • Offering: 私有化部署

如果你在 管理员 > Geo > 站点 或者 同步状态 Rake 任务 中注意到复制或验证失败,可以尝试使用以下一般步骤解决这些失败:

  1. Geo 会自动重试失败。如果这些失败是新的且数量少,或者你怀疑根本原因已经解决,那么你可以等待看看这些失败是否会消失。
  2. 如果失败已经存在很长时间,那么已经进行了多次重试,并且根据失败类型,自动重试之间的间隔已增加到最长 4 小时。如果你怀疑根本原因已经解决,可以手动重试复制或验证以避免等待。
  3. 如果失败仍然存在,请使用以下部分尝试解决它们。

手动重试复制或验证#

在次级 Geo 站点的 Rails 控制台中,你可以:

重新同步和重新验证单个组件#

你可以强制重新同步和重新验证单个项目,适用于所有由自助服务框架管理的组件类型,使用 UI。在次级站点,访问管理员 > Geo > 复制

但是,如果这不起作用,你可以使用 Rails 控制台执行相同的操作。以下部分描述了如何在 Rails 控制台中使用内部应用程序命令同步或验证单个记录,同步或异步。

获取一个 Replicator 实例#

更改数据的命令如果不正确运行或在正确条件下运行,可能会造成损害。始终在测试环境中首先运行命令,并准备好一个备份实例以恢复。

在执行任何同步或验证操作之前,你需要获取一个 Replicator 实例。

首先,视乎你想做什么,在主站点次级站点启动一个 Rails 控制台会话

主站点

  • 你可以校验一个资源的校验和

次级站点

  • 你可以同步一个资源
  • 你可以校验一个资源,并将其校验和与主站点的校验和进行比较

接下来,运行以下代码段之一以获取一个 Replicator 实例。

给定模型记录的 ID#
ruby
model_record = Packages::PackageFile.find_by(id: 123) replicator = model_record.replicator
给定注册记录的 ID#
  • 432 替换为实际的 ID。注意,注册记录可能与其跟踪的模型记录具有相同的 ID 值,也可能不相同。
  • Geo::PackageFileRegistry 替换为任何 Geo 仓库类

在次级 Geo 站点:

ruby
registry_record = Geo::PackageFileRegistry.find_by(id: 432) replicator = registry_record.replicator
给定注册记录的 last_sync_failure 中的错误消息#
  • Geo::PackageFileRegistry 替换为任何 Geo 仓库类
  • error message here 替换为实际的错误消息。
ruby
registry = Geo::PackageFileRegistry.find_by("last_sync_failure LIKE '%error message here%'") replicator = registry.replicator
给定注册记录的 verification_failure 中的错误消息#
  • Geo::PackageFileRegistry 替换为任何 Geo 仓库类
  • error message here 替换为实际的错误消息。
ruby
registry = Geo::PackageFileRegistry.find_by("verification_failure LIKE '%error message here%'") replicator = registry.replicator

使用 Replicator 实例执行操作#

在你将 Replicator 实例存储到 replicator 变量后,你可以执行许多操作:

在控制台中同步#

此代码段仅在次级站点中有效。

这将在控制台中同步执行同步代码,因此你可以观察同步一个资源需要多长时间,或查看完整的错误回溯。

ruby
replicator.sync

可选地,将控制台的日志级别设置为比配置的日志级别更详细,然后执行同步:

ruby
Rails.logger.level = :debug
在控制台中校验或验证#

此代码段在任何主站点次级站点中都有效。

主站点,它校验资源并将结果存储在主极狐GitLab数据库中。在次级站点,它校验资源,将其与主极狐GitLab数据库(由主站点生成)的校验和进行比较,并将结果存储在 Geo 跟踪数据库中。

这将在控制台中同步执行校验和验证代码,因此你可以观察需要多长时间,或查看完整的错误回溯。

ruby
replicator.verify
在 Sidekiq 任务中同步#

此代码段仅在次级站点中有效。

它为 Sidekiq 排队一个任务以执行资源的 同步

ruby
replicator.enqueue_sync
在 Sidekiq 任务中验证#

此代码段在任何主站点次级站点中都有效。

它为 Sidekiq 排队一个任务以执行资源的校验或验证

ruby
replicator.verify_async
获取模型记录#

此代码段在任何主站点次级站点中都有效。

ruby
replicator.model_record
获取注册记录#

此代码段仅在次级站点中有效,因为仓库表存储在 Geo 跟踪数据库中。

ruby
replicator.registry

Geo 数据类型模型类#

Geo 数据类型是一个或多个极狐GitLab功能所需的特定数据类,用于存储相关数据,并由 Geo 复制到次级站点。

  • Blob 类型:
    • Ci::JobArtifact
    • Ci::PipelineArtifact
    • Ci::SecureFile
    • LfsObject
    • MergeRequestDiff
    • Packages::PackageFile
    • PagesDeployment
    • Terraform::StateVersion
    • Upload
    • DependencyProxy::Manifest
    • DependencyProxy::Blob
  • Git 仓库类型:
    • DesignManagement::Repository
    • ProjectRepository
    • ProjectWikiRepository
    • SnippetRepository
    • GroupWikiRepository
  • 其他类型:
    • ContainerRepository

主要的类类型是仓库、模型和 Replicator。如果你有其中一个类的实例,你可以获得其他类。仓库和模型主要管理 PostgreSQL 数据库状态。Replicator 知道如何复制或验证非 PostgreSQL 数据(文件/Git 仓库/容器仓库)。

Geo 仓库类#

在极狐GitLab Geo 的上下文中,仓库记录指的是 Geo 跟踪数据库中的仓库表。每个记录在主极狐GitLab数据库中跟踪一个可复制对象,例如一个 LFS 文件或一个项目 Git 仓库。对应于 Geo 仓库表的 Rails 模型可以查询的是:

  • Blob 类型:
    • Geo::CiSecureFileRegistry
    • Geo::DependencyProxyBlobRegistry
    • Geo::DependencyProxyManifestRegistry
    • Geo::JobArtifactRegistry
    • Geo::LfsObjectRegistry
    • Geo::MergeRequestDiffRegistry
    • Geo::PackageFileRegistry
    • Geo::PagesDeploymentRegistry
    • Geo::PipelineArtifactRegistry
    • Geo::ProjectWikiRepositoryRegistry
    • Geo::SnippetRepositoryRegistry
    • Geo::TerraformStateVersionRegistry
    • Geo::UploadRegistry
  • Git 仓库类型:
    • Geo::DesignManagementRepositoryRegistry
    • Geo::ProjectRepositoryRegistry
    • Geo::ProjectWikiRepositoryRegistry
    • Geo::SnippetRepositoryRegistry
    • Geo::GroupWikiRepositoryRegistry
  • 其他类型:
    • Geo::ContainerRepositoryRegistry

重新同步和重新验证多个组件#

History
    • 大量重新同步和重新验证在极狐GitLab 16.5 中新增。
更改数据的命令如果不正确运行或在正确条件下运行,可能会造成损害。始终在测试环境中首先运行命令,并准备好一个备份实例以恢复。

以下部分描述了如何在 Rails 控制台中使用内部应用程序命令进行批量复制或验证。

重新同步一个组件的所有资源#

你可以从 UI 中安排一个组件的所有资源的完整重新同步:

  1. 在左侧边栏底部,选择 管理员
  2. 选择 Geo > 站点
  3. 复制详情下,选择所需的组件。
  4. 选择 重新同步所有

或者, 在次级 Geo 站点上启动一个 Rails 控制台会话 以获取更多信息,或使用下面的代码段手动执行这些操作。

更改数据的命令如果不正确运行或在正确条件下运行,可能会造成损害。始终在测试环境中首先运行命令,并准备好一个备份实例以恢复。
同步所有失败同步的一个组件的资源#

以下脚本:

  • 循环遍历所有失败的仓库。
  • 显示 Geo 同步和验证元数据,包括最后一次失败的原因。
  • 尝试重新同步仓库。
  • 如果失败发生,报告失败的原因。
  • 可能需要一些时间来完成。每个仓库检查必须完成才能报告结果。如果你的会话超时,采取措施以允许进程继续运行,例如启动一个 screen 会话,或使用 Rails runnernohup 运行它。
ruby
1Geo::ProjectRepositoryRegistry.failed.find_each do |registry| 2 begin 3 puts "ID: #{registry.id}, Project ID: #{registry.project_id}, Last Sync Failure: '#{registry.last_sync_failure}'" 4 registry.replicator.sync 5 puts "Sync initiated for registry ID: #{registry.id}" 6 rescue => e 7 puts "ID: #{registry.id}, Project ID: #{registry.project_id}, Failed: '#{e}'", e.backtrace.join("\n") 8 end 9end; nil

在所有站点上重新验证一个组件#

如果主站点的校验和有问题,那么你需要让主站点重新计算校验和。这样就实现了“全面重新验证”,因为在每个校验和在主站点重新计算后,会生成事件传播到所有次级站点,导致它们重新计算其校验和并比较值。任何不匹配都会将仓库标记为 sync failed,这会导致安排同步重试。

UI 不提供执行“全面重新验证”的按钮。你可以通过将主站点的“重新验证间隔”设置为 1(天)在 Admin > Geo > Nodes > Edit 中模拟这一过程。然后,主站点将重新计算任何校验和超过 1 天的资源的校验和。

可选地,你可以手动完成此操作:

  1. SSH 进入主站点中的极狐GitLab Rails 节点。

  2. 打开 Rails 控制台

  3. Upload 替换为任何 Geo 数据类型模型类, 将所有资源标记为 pending verification

    ruby
    Upload.verification_state_table_class.each_batch do |relation| relation.update_all(verification_state: 0) end
在主站点上重新验证所有校验和失败的资源#

系统会自动重新验证在主站点上校验和失败的所有资源,但它使用一种渐进回退方案以避免过多的失败。

可选地,例如如果你已经完成了尝试的干预,可以手动触发更早的重新验证:

  1. SSH 进入主站点中的极狐GitLab Rails 节点。

  2. 打开 Rails 控制台

  3. Upload 替换为任何 Geo 数据类型模型类, 将所有资源标记为 pending verification

    ruby
    Upload.verification_state_table_class.where(verification_state: 3).each_batch do |relation| relation.update_all(verification_state: 0) end

在一个次级站点上重新验证一个组件#

如果你认为主站点校验和是正确的,可以从 UI 中为一个次级站点安排一个组件的重新验证:

  1. 在左侧边栏底部,选择 管理员
  2. 选择 Geo > 站点
  3. 复制详情下,选择所需的组件。
  4. 选择 重新验证所有

错误#

在主 Geo 站点上上传失败的验证#

如果在主 Geo 站点上验证某些上传失败,verification_checksum = nil 并且 verification_failure 包含 Error during verification: undefined method `underscore' for NilClass:ClassThe model which owns this Upload is missing.,这是由于孤立的上传。拥有上传的父记录(上传的“模型”)以某种方式被删除,但上传记录仍然存在。这通常是由于应用程序中的错误引起的,通过实现“模型”的批量删除而忘记批量删除其关联的上传记录引入的。因此,这些验证失败实际上不是验证失败,而是由于 Postgres 中的坏数据导致的错误。

你可以在主 Geo 站点的 geo.log 文件中找到这些错误。

要确认模型记录丢失,可以在主 Geo 站点上运行一个 Rake 任务:

shell
sudo gitlab-rake gitlab:uploads:check

你可以在主 Geo 站点上删除这些上传记录以消除这些失败,通过在 Rails 控制台中运行以下脚本:

ruby
1def delete_orphaned_uploads(dry_run: true) 2 if dry_run 3 p "This is a dry run. Upload rows will only be printed." 4 else 5 p "This is NOT A DRY RUN! Upload rows will be deleted from the DB!" 6 end 7 8 subquery = Geo::UploadState.where("(verification_failure LIKE 'Error during verification: The model which owns this Upload is missing.%' OR verification_failure = 'Error during verification: undefined method `underscore'' for NilClass:Class') AND verification_checksum IS NULL") 9 uploads = Upload.where(upload_state: subquery) 10 p "Found #{uploads.count} uploads with a model that does not exist" 11 12 uploads_deleted = 0 13 begin 14 uploads.each do |upload| 15 16 if dry_run 17 p upload 18 else 19 uploads_deleted=uploads_deleted + 1 20 p upload.destroy! 21 end 22 rescue => e 23 puts "checking upload #{upload.id} failed with #{e.message}" 24 end 25 end 26 27 p "#{uploads_deleted} remote objects were destroyed." unless dry_run 28end

以上脚本定义了一个名为 delete_orphaned_uploads 的方法,你可以像这样调用它来进行干运行:

ruby
delete_orphaned_uploads(dry_run: true)

实际删除孤立的上传行:

ruby
delete_orphaned_uploads(dry_run: false)

消息: "Error during verification","error":"File is not checksummable"#

如果你在主站点 geo.log 中遇到这些错误,它们也会反映在 UI 中的管理员 > Geo > 站点下。要消除这些错误,可以识别生成消息的特定 blob,以便检查它。

  1. 在主站点的 Puma 或 Sidekiq 节点中,打开 Rails 控制台
  2. 运行以下代码段以查找包含 File is not checksummable 消息的受影响的产物:
下面提供的示例使用 `JobArtifact` blob 类型;然而,同样的解决方案适用于 Geo 使用的任何 blob 类型。
ruby
artifacts = Ci::JobArtifact.verification_failed.where("verification_failure like '%File is not checksummable%'");1 puts "Found #{artifacts.count} artifacts that failed verification with 'File is not checksummable'. The first one:" pp artifacts.first

如果确定需要恢复受影响的文件,则可以探索以下选项(非详尽)来恢复丢失的文件:

  • 检查次级站点是否有对象并手动将它们复制到主站点。
  • 查看旧备份并手动将对象复制回主站点。
  • 随机检查一些以尝试确定销毁记录是否可能,例如,如果它们都是非常旧的产物,那么它们可能不是关键数据。

通常,这种错误发生在一个文件被 Geo 校验,然后从主站点丢失之后。在识别受影响的文件之后,你应该从 UI 检查文件所属的项目,以决定是否可以删除文件引用。如果可以,使用以下不可逆的代码段销毁引用:

ruby
1def destroy_artifacts_not_checksummable 2 artifacts = Ci::JobArtifact.verification_failed.where("verification_failure like '%File is not checksummable%'");1 3 puts "Found #{artifacts.count} artifacts that failed verification with 'File is not checksummable'." 4 puts "Enter 'y' to continue: " 5 prompt = STDIN.gets.chomp 6 if prompt != 'y' 7 puts "Exiting without action..." 8 return 9 end 10 11 puts "Destroying all..." 12 artifacts.destroy_all 13end 14 15destroy_artifacts_not_checksummable

错误: Error syncing repository: 13:fatal: could not read Username#

last_sync_failure 错误 Error syncing repository: 13:fatal: could not read Username for 'https://gitlab.example.com': terminal prompts disabled 表示在 Geo 克隆或获取请求期间 JWT 认证失败。 有关更多上下文,请参阅 Geo (development) > Authentication

首先,检查系统时钟是否同步。运行健康检查 Rake 任务,或者 手动检查次级站点上的所有 Sidekiq 节点和主站点上的所有 Puma 节点上的 date 是否相同。

如果系统时钟已同步,则在 Git 获取进行其两个单独的 HTTP 请求之间进行计算时,JWT 令牌可能会过期。

要验证是否遇到此问题:

  1. Rails 控制台中修改代码以将令牌的有效期从 1 分钟增加到 10 分钟。在次级站点的 Rails 控制台中运行以下代码:

    ruby
    1module Gitlab; module Geo; class BaseRequest 2 private 3 def geo_auth_token(message) 4 signed_data = Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes).sign_and_encode_data(message) 5 6 "#{GITLAB_GEO_AUTH_TOKEN_TYPE} #{signed_data}" 7 end 8end;end;end
  2. 在同一 Rails 控制台中,重新同步受影响的项目:

    ruby
    Project.find_by_full_path('<mygroup/mysubgroup/myproject>').replicator.resync
  3. 查看同步状态:

    ruby
    Project.find_by_full_path('<mygroup/mysubgroup/myproject>').replicator.registry
  4. 如果 last_sync_failure 不再包含错误 fatal: could not read Username,那么你受到了此问题的影响。状态现在应该是 2,意味着“已同步”。如果是这样,那么你应该升级到包含修复的极狐GitLab版本。

要解决此问题,必须在次级站点的所有 Sidekiq 节点上热修补以延长 JWT 过期时间:

  1. 编辑 /opt/gitlab/embedded/service/gitlab-rails/ee/lib/gitlab/geo/signed_data.rb

  2. 找到 Gitlab::Geo::SignedData.new(geo_node: requesting_node) 并添加 , validity_period: 10.minutes

    diff
    - Gitlab::Geo::SignedData.new(geo_node: requesting_node) + Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes)
  3. 重启 Sidekiq:

    shell
    sudo gitlab-ctl restart sidekiq
  4. 除非你升级到包含修复的版本,否则每次极狐GitLab升级后都必须重复此解决方法。

错误: fetch remote: signal: terminated: context deadline exceeded 在正好 3 小时时#

如果在同步 Git 仓库时,Git 获取在正好三小时时失败:

  1. 编辑 /etc/gitlab/gitlab.rb 以将 Git 超时从默认的 10800 秒增加:

    ruby
    # Git 超时,以秒为单位 gitlab_rails['gitlab_shell_git_timeout'] = 21600
  2. 重新配置极狐GitLab:

    shell
    sudo gitlab-ctl reconfigure

错误 Failed to open TCP connection to localhost:5000 在配置仓库复制时在次级站点#

在次级站点配置容器仓库复制时,可能会遇到以下错误:

plaintext
Failed to open TCP connection to localhost:5000 (Connection refused - connect(2) for \"localhost\" port 5000)"

如果在次级站点没有启用容器仓库,则会发生此错误。要解决它,请检查容器仓库是否在次级站点启用。注意,如果禁用了 Let’s Encrypt 集成,则容器仓库也被禁用,你必须手动配置它

消息: Synchronization failed - Error syncing repository#

如果大仓库受此问题影响,它们的重新同步可能需要很长时间,并可能对你的 Geo 站点、存储和网络系统造成显著负担。

以下错误消息指示在同步仓库时出现一致性检查错误:

plaintext
Synchronization failed - Error syncing repository [..] fatal: fsck error in packed object

几个问题可能会触发此错误。例如,电子邮件地址的问题:

plaintext
Error syncing repository: 13:fetch remote: "error: object <SHA>: badEmail: invalid author/committer line - bad email fatal: fsck error in packed object fatal: fetch-pack: invalid index-pack output

另一个可能触发此错误的问题是 object <SHA>: hasDotgit: contains '.git'。检查特定错误,因为你可能在所有仓库中有多个问题。

第二个同步错误也可能由仓库检查问题引起:

plaintext
Error syncing repository: 13:Received RST_STREAM with error code 2.

这些错误可以通过立即同步所有失败的仓库观察到。

删除导致一致性错误的畸形对象涉及重写仓库历史,通常不是一个选项。

要忽略这些一致性检查,请重新配置 Gitaly 在次级 Geo 站点忽略这些 git fsck 问题。 以下配置示例:

  • 使用从极狐GitLab 16.0 开始所需的新配置结构。
  • 忽略五个常见检查失败。

极狐GitLab Gitaly 文档提供了更多细节 关于其他 Git 检查失败和更早版本的极狐GitLab。

ruby
1gitaly['configuration'] = { 2 git: { 3 config: [ 4 { key: "fsck.duplicateEntries", value: "ignore" }, 5 { key: "fsck.badFilemode", value: "ignore" }, 6 { key: "fsck.missingEmail", value: "ignore" }, 7 { key: "fsck.badEmail", value: "ignore" }, 8 { key: "fsck.hasDotgit", value: "ignore" }, 9 { key: "fetch.fsck.duplicateEntries", value: "ignore" }, 10 { key: "fetch.fsck.badFilemode", value: "ignore" }, 11 { key: "fetch.fsck.missingEmail", value: "ignore" }, 12 { key: "fetch.fsck.badEmail", value: "ignore" }, 13 { key: "fetch.fsck.hasDotgit", value: "ignore" }, 14 { key: "receive.fsck.duplicateEntries", value: "ignore" }, 15 { key: "receive.fsck.badFilemode", value: "ignore" }, 16 { key: "receive.fsck.missingEmail", value: "ignore" }, 17 { key: "receive.fsck.badEmail", value: "ignore" }, 18 { key: "receive.fsck.hasDotgit", value: "ignore" }, 19 ], 20 }, 21}

极狐GitLab 16.1 及更高版本包括一个增强功能,可能解决其中一些问题。

你还可能收到错误消息 Synchronization failed - Error syncing repository,以及以下日志消息。 该错误表示次级 Geo 站点文件系统上某个仓库的 .git/config 文件中预期的 Geo 远程不存在:

json
1{ 2 "created": "@1603481145.084348757", 3 "description": "Error received from peer unix:/var/opt/gitlab/gitaly/gitaly.socket", 45 "grpc_message": "exit status 128", 6 "grpc_status": 13 7} 8{9 "grpc.request.fullMethod": "/gitaly.RemoteService/FindRemoteRootRef", 10 "grpc.request.glProjectPath": "<namespace>/<project>", 1112 "level": "error", 13 "msg": "fatal: 'geo' does not appear to be a git repository 14 fatal: Could not read from remote repository. …", 15}

要解决此问题:

  1. 在次级 Geo 站点的 web 界面上登录。

  2. 备份.git 文件夹

  3. 可选。 Spot-check 其中一些 ID 是否确实对应于 一个已知 Geo 复制失败的项目。 使用 fatal: 'geo' 作为 grep 条款和以下 API 调用:

    shell
    curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<first_failed_geo_sync_ID>"
  4. 进入 Rails 控制台 并运行:

    ruby
    1failed_project_registries = Geo::ProjectRepositoryRegistry.failed 2 3if failed_project_registries.any? 4 puts "Found #{failed_project_registries.count} failed project repository registry entries:" 5 6 failed_project_registries.each do |registry| 7 puts "ID: #{registry.id}, Project ID: #{registry.project_id}, Last Sync Failure: '#{registry.last_sync_failure}'" 8 end 9else 10 puts "No failed project repository registry entries found." 11end
  5. 运行以下命令为每个项目执行新的同步:

    ruby
    failed_project_registries.each do |registry| registry.replicator.sync puts "Sync initiated for registry ID: #{registry.id}, Project ID: #{registry.project_id}" end

回填期间的失败#

回填期间,失败被安排在回填队列的末尾重试,因此这些失败只有在回填完成后才会清除。

消息: unexpected disconnect while reading sideband packet#

不稳定的网络条件可能导致 Gitaly 在尝试从主站点获取大仓库数据时失败。这些条件可能导致此错误:

plaintext
curl 18 transfer closed with outstanding read data remaining & fetch-pack: unexpected disconnect while reading sideband packet

如果必须在站点之间从头开始复制仓库,则更有可能发生此错误。

Geo 多次重试,但如果传输持续被网络故障中断,则可以使用 rsync 等替代方法绕过 git 并创建任何 Geo 无法复制的仓库的初始副本。

我们建议单独传输每个失败的仓库,并在每次传输后检查一致性。按照单目标 rsync 指令 将每个受影响的仓库从主站点传输到次级站点。

在 Geo 次级站点中查找仓库检查失败#

所有仓库数据类型已在极狐GitLab 16.3 中迁移到 Geo 自助服务框架。

对于极狐GitLab 16.2 及更早版本:

为所有项目启用时,仓库检查也在 Geo 次级站点上执行。元数据存储在 Geo 跟踪数据库中。

Geo 次级站点上的仓库检查失败不一定意味着复制问题。以下是解决这些失败的一般方法。

  1. 按照以下方法找到受影响的仓库,以及它们的记录错误
  2. 尝试诊断特定的 git fsck 错误。可能的错误范围很广,尝试将它们放入搜索引擎中。
  3. 测试受影响仓库的典型功能。从次级站点拉取,查看文件。
  4. 检查主站点的仓库副本是否具有相同的 git fsck 错误。如果你计划进行故障切换,则考虑优先确保次级站点拥有主站点的相同信息。确保你有主站点的备份,并遵循计划故障切换指南
  5. 推送到主站点,并检查更改是否复制到次级站点。
  6. 如果复制没有自动工作,尝试手动同步仓库。

启动一个 Rails 控制台会话 以执行以下基本故障排除步骤。

更改数据的命令如果不正确运行或在正确条件下运行,可能会造成损害。始终在测试环境中首先运行命令,并准备好一个备份实例以恢复。

获取仓库检查失败的仓库数量#

ruby
Geo::ProjectRegistry.where(last_repository_check_failed: true).count

查找仓库检查失败的仓库#

ruby
Geo::ProjectRegistry.where(last_repository_check_failed: true)

重置 Geo 次级站点复制#

如果你的次级站点处于损坏状态,并希望重置复制状态以重新开始,有一些步骤可以帮助你:

  1. 停止 Sidekiq 和 Geo 日志游标。

    可以使 Sidekiq 优雅地停止,但让它停止获取新任务并 等待当前任务完成处理。

    你需要发送一个 SIGTSTP 终止信号进行第一阶段,然后当所有任务完成后发送一个 SIGTERM。 否则,只需使用 gitlab-ctl stop 命令。

    shell
    1gitlab-ctl status sidekiq 2# run: sidekiq: (pid 10180) <- 这是你将使用的 PID 3kill -TSTP 10180 # 更改为正确的 PID 4 5gitlab-ctl stop sidekiq 6gitlab-ctl stop geo-logcursor

    你可以查看 Sidekiq 日志以了解 Sidekiq 任务处理何时完成:

    shell
    gitlab-ctl tail sidekiq
  2. 清除 Gitaly/Gitaly 集群数据。

shell
mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old sudo gitlab-ctl reconfigure
  1. 可选。禁用 Praefect 内部负载均衡器。
    1. 在每个 Praefect 服务器上停止 Praefect:

      shell
      sudo gitlab-ctl stop praefect
    2. 重置 Praefect 数据库:

      shell
      sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "DROP DATABASE praefect_production WITH (FORCE);" sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "CREATE DATABASE praefect_production WITH OWNER=praefect ENCODING=UTF8;"
    3. 在每个 Gitaly 节点上重命名/删除仓库数据:

      shell
      sudo mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old sudo gitlab-ctl reconfigure
    4. 在你的 Praefect 部署节点上运行重新配置以设置数据库:

      shell
      sudo gitlab-ctl reconfigure
    5. 在每个 Praefect 服务器上启动 Praefect:

      shell
      sudo gitlab-ctl start praefect
    6. 可选。如果你禁用了它,重新激活 Praefect 内部负载均衡器。

你可能希望在确认不再需要后,将 `/var/opt/gitlab/git-data/repositories.old` 删除,以节省磁盘空间。
  1. 可选。重命名其他数据文件夹并创建新文件夹。

    你可能仍然在次级站点上有一些文件,这些文件已从主站点删除,但尚未反映此删除。如果你跳过此步骤,这些文件不会从 Geo 次级站点删除。

    任何上传的内容(如文件附件、头像或 LFS 对象)存储在以下路径之一的子文件夹中:

    • /var/opt/gitlab/gitlab-rails/shared
    • /var/opt/gitlab/gitlab-rails/uploads

    要重命名所有这些:

    shell
    1gitlab-ctl stop 2 3mv /var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared.old 4mkdir -p /var/opt/gitlab/gitlab-rails/shared 5 6mv /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads.old 7mkdir -p /var/opt/gitlab/gitlab-rails/uploads 8 9gitlab-ctl start postgresql 10gitlab-ctl start geo-postgresql

    重新配置以重新创建文件夹并确保权限和所有权正确:

    shell
    gitlab-ctl reconfigure
  2. 重置跟踪数据库。

    如果你跳过了可选步骤 3,确保 `geo-postgresql` 和 `postgresql` 服务正在运行。
    shell
    gitlab-rake db:drop:geo DISABLE_DATABASE_ENVIRONMENT_CHECK=1 # 在次级应用节点上 gitlab-ctl reconfigure # 在跟踪数据库节点上 gitlab-rake db:migrate:geo # 在次级应用节点上
  3. 重启之前停止的服务。

    shell
    gitlab-ctl start