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

升级迁移

  • 版本:Free, Premium, Ultimate
  • 提供方式:GitLab Self-Managed

升级 GitLab 时,需要检查两种类型的迁移:

  • 数据库迁移。
  • 高级搜索迁移。

数据库后台迁移

为减少完成这些迁移所需的时间,增加可以处理 background_migration 队列中作业的 Sidekiq workers 数量。

批量后台迁移

为批量更新数据库表,GitLab 可以使用批量后台迁移。这些迁移由 GitLab 开发人员创建,并在升级时自动运行。然而,这类迁移范围有限,主要用于帮助将某些 integer 数据库列迁移到 bigint。这是为了防止某些表出现整数溢出。

批量后台迁移由 Sidekiq 处理,并独立运行,因此在迁移处理过程中,实例可以保持正常运行。但是,在运行批量后台迁移时,大型且使用频繁的实例性能可能会下降。您应该 主动监控 Sidekiq 状态 直到所有迁移完成。

检查批量后台迁移状态

您可以在 GitLab UI 中检查批量后台迁移的状态,或通过直接查询数据库。在升级 GitLab 之前,所有迁移必须具有 Finished 状态。

如果迁移未完成且您尝试升级 GitLab,您可能会看到此错误:

期望给定配置的批量后台迁移标记为 'finished',但它是 'active':

如果您遇到此错误, 查看选项 了解 如何完成 GitLab 升级所需的批量后台迁移。

从 GitLab UI

先决条件:

  • 您必须拥有实例的管理员权限。

要检查批量后台迁移的状态:

  1. 在左侧边栏底部,选择 管理员
  2. 选择 监控 > 后台迁移
  3. 选择 排队中完成中 查看未完成的迁移, 选择 失败 查看失败的迁移。
从数据库

先决条件:

  • 您必须拥有实例的管理员权限。

要直接查询数据库以获取批量后台迁移的状态:

  1. 根据您实例的安装方法说明,登录到 psql 提示符。例如,Linux 包安装使用 sudo gitlab-psql

  2. 要查看未完成的批量后台迁移的详细信息,在 psql 会话中运行以下查询:

    SELECT
      job_class_name,
      table_name,
      column_name,
      job_arguments
    FROM batched_background_migrations
    WHERE status NOT IN(3, 6);

或者,您可以使用 gitlab-psql -c "<QUERY>" 包装查询来检查批量后台迁移的状态:

gitlab-psql -c "SELECT job_class_name, table_name, column_name, job_arguments FROM batched_background_migrations WHERE status NOT IN(3, 6);"

如果查询返回零行,则所有批量后台迁移都已完成。

启用或禁用高级功能

批量后台迁移提供功能标志,使您可以自定义迁移或完全暂停它们。这些功能标志仅应由了解相关风险的高级用户禁用。

暂停批量后台迁移

禁用已发布功能时可能存在 风险。 有关详细信息,请参阅每个功能的历史记录。

要暂停正在进行的批量后台迁移, 禁用批量后台迁移功能。 禁用该功能将完成当前批次的迁移,然后等待功能重新启用后再启动下一批次。

先决条件:

  • 您必须拥有实例的管理员权限。

使用以下数据库查询查看当前批量后台迁移的状态:

  1. 获取正在运行的迁移的 ID:

    SELECT
     id,
     job_class_name,
     table_name,
     column_name,
     job_arguments
    FROM batched_background_migrations
    WHERE status NOT IN(3, 6);
  2. 运行此查询,将 XX 替换为您在上一步中获得的 ID, 以查看迁移的状态:

    SELECT
     started_at,
     finished_at,
     finished_at - started_at AS duration,
     min_value,
     max_value,
     batch_size,
     sub_batch_size
    FROM batched_background_migration_jobs
    WHERE batched_background_migration_id = XX
    ORDER BY id DESC
    limit 10;
  3. 在几分钟内多次运行查询,确保没有添加新行。 如果没有添加新行,则迁移已暂停。

  4. 确认迁移已暂停后,重新启动迁移(使用之前提到的 enable 命令), 以在准备就绪时继续处理批次。在大型实例上,后台迁移可能需要长达 48 小时才能完成每个批次。

自动批量大小优化

禁用已发布功能时可能存在 风险。 有关详细信息,请参阅此功能的历史记录。

在 GitLab Self-Managed 上,默认情况下此功能可用。要隐藏此功能,请要求管理员 禁用功能标志 optimize_batched_migrations。 在 GitLab.com 上,此功能可用。在 GitLab Dedicated 上,此功能不可用。

为最大化批量后台迁移的吞吐量(按每时间单位更新的元组数量),批量大小会根据前一批次的完成时间自动调整。

并行执行

禁用已发布功能时可能存在 风险。 有关详细信息,请参阅此功能的历史记录。

为加快批量后台迁移的执行速度,两个迁移同时执行。

可以访问 GitLab Rails 控制台的 GitLab 管理员 可以更改 并行执行的批量后台迁移数量:

ApplicationSetting.update_all(database_max_running_batched_background_migrations: 4)

解决失败的批量后台迁移

如果批量后台迁移失败,修复并重试。 如果迁移继续失败并出现错误,可以:

修复并重试迁移

所有失败的批量后台迁移都必须解决才能升级到 GitLab 的更新版本。如果您 检查状态, 某些迁移可能在 失败 选项卡中以 失败 状态显示:

失败的批量后台迁移表。

要确定批量后台迁移失败的原因, 查看失败错误日志 或在 UI 中查看错误信息。

先决条件:

  • 您必须拥有实例的管理员权限。
  1. 在左侧边栏底部,选择 管理员
  2. 选择 监控 > 后台迁移
  3. 选择 失败 选项卡。这将显示失败的批量后台迁移列表。
  4. 选择失败的 迁移 以查看迁移参数和失败的作业。
  5. 失败的作业 下,选择每个 ID 以查看作业失败的原因。

如果您是 GitLab 客户,可以考虑提交 支持请求 来调试批量后台迁移失败的原因。

要纠正问题,您可以重试失败的迁移。

先决条件:

  • 您必须拥有实例的管理员权限。
  1. 在左侧边栏底部,选择 管理员
  2. 选择 监控 > 后台迁移
  3. 选择 失败 选项卡。这将显示失败的批量后台迁移列表。
  4. 点击重试按钮 ( retry ) 选择要重试的失败的批量后台迁移。

要监控重试的批量后台迁移,您可以 定期检查批量后台迁移的状态

手动完成失败的迁移

要手动完成因错误而失败的批量后台迁移, 使用失败错误日志或数据库中的信息:

  1. 查看失败错误日志 并查找 An error has occurred, all later migrations canceled 错误消息,如下所示:

    StandardError: 发生错误,所有后续迁移已取消:
    
    期望给定配置的批量后台迁移标记为
    'finished',但它是 'active':
      {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob",
       :table_name=>"push_event_payloads",
       :column_name=>"event_id",
       :job_arguments=>[["event_id"],
       ["event_id_convert_to_bigint"]]
      }
  2. 运行以下命令,将尖括号中的值替换为正确的参数:

    sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']

    当处理多个参数时,例如 [["id"],["id_convert_to_bigint"]],使用反斜杠 \ 转义 每个参数之间的逗号以防止无效字符错误。 例如,要完成上一步的迁移:

    sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']
  1. 检查数据库中迁移的状态

  2. 使用查询结果构建迁移命令,将尖括号中的值 替换为正确的参数:

    sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']

    例如,如果查询返回以下数据:

    • job_class_name: CopyColumnUsingBackgroundMigrationJob
    • table_name: events
    • column_name: id
    • job_arguments: [["id"], ["id_convert_to_bigint"]]

    当处理多个参数时,例如 [["id"],["id_convert_to_bigint"]],使用反斜杠 \ 转义 每个参数之间的逗号以防止无效字符错误。 job_arguments 参数值中的每个逗号都必须用反斜杠转义。

    例如:

    sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,ci_builds,id,'[["id"\, "stage_id"]\,["id_convert_to_bigint"\,"stage_id_convert_to_bigint"]]']
将失败的迁移标记为已完成

在使用这些说明之前,联系 GitLab 支持。 此操作可能导致数据丢失,并以难以恢复的方式使您的实例失败。

在某些情况下,后台迁移可能会失败:当跳过太多版本升级时, 或向后不兼容的数据库架构更改时。(例如,请参阅 issue 393216)。 失败的后台迁移会阻止应用程序的进一步升级。

当确定后台迁移可以"安全"跳过时,可以手动将其标记为已完成:

确保在继续之前创建备份。

# Start the rails console

connection = ApplicationRecord.connection # or Ci::ApplicationRecord.connection, depending on which DB was the migration scheduled

Gitlab::Database::SharedModel.using_connection(connection) do
  migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration(
    Gitlab::Database.gitlab_schemas_for_connection(connection),
    'BackfillUserDetailsFields',
    :users,
    :id,
    []
  )

  # mark all jobs completed
  migration.batched_jobs.update_all(status: Gitlab::Database::BackgroundMigration::BatchedJob.state_machine.states['succeeded'].value)
  migration.update_attribute(:status, Gitlab::Database::BackgroundMigration::BatchedMigration.state_machine.states[:finished].value)
end

同步运行所有后台迁移

在某些情况下,您可能希望在维护窗口期间强制后台迁移在前台运行。

此脚本可能在所有迁移完成之前超时/退出。您可以再次运行它,直到所有迁移完成。

# Start the rails console

databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml

Gitlab::Database.database_base_models.each do |database_name, model|
  Gitlab::Database::SharedModel.using_connection(model.connection) do
    Gitlab::Database::BackgroundMigration::BatchedMigration.with_status([:paused, :active]).find_each(batch_size: 100) do |migration|
      puts "#{database_name}: Finalizing migration #{migration.job_class_name} (ID: #{migration.id})... "
      Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(
        migration.job_class_name,
        migration.table_name,
        migration.column_name,
        Gitlab::Json.parse(migration.job_arguments),
        connection: model.connection
      )
      puts("done!\n")
    end
  end
end

高级搜索迁移

检查待处理的迁移

  • 版本:Premium, Ultimate
  • 提供方式:GitLab Self-Managed

本部分仅适用于您已启用 Elasticsearch 集成 的情况。 主要版本升级要求所有 高级搜索迁移 从当前版本最近的次要版本完成。 您可以通过运行以下命令查找待处理的迁移。

sudo gitlab-rake gitlab:elastic:list_pending_migrations
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:elastic:list_pending_migrations

如果您处于漫长的升级路径且有许多待处理的迁移,您可能需要配置 重新排队索引工作进程非代码索引的分片数 来加快索引速度。 另一个选择是忽略待处理的迁移,并在将 GitLab 升级到目标版本后 重新索引实例。 您还可以使用 启用 Elasticsearch 搜索 设置在此过程中禁用高级搜索。

索引大型实例存在风险。 有关更多信息,请参阅 高效索引大型实例