极狐 GitLab

升级前检查迁移

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

使用 Rake 任务管理后台迁移#

极狐GitLab 提供了一组 Rake 任务,用于从命令行管理后台迁移。当管理界面不可用时(例如在停机升级或维护窗口期间),这些任务对需要管理后台迁移的极狐GitLab 私有化部署管理员特别有用。

所有 Rake 任务都适用于所有数据库(main 和 ci),并使用统一的迁移 ID 格式:{database}_{id}。例如,main_85 指 main 数据库中 ID 为 85 的迁移,ci_10 指 ci 数据库中 ID 为 10 的迁移。

对于活跃的迁移,progress 列在可用时会包含预计剩余时间(例如 42.50% (estimated time remaining: 5 minutes))。

列出所有后台迁移#

要查看所有数据库中的所有批处理后台迁移:

shell
sudo gitlab-rake gitlab:background_migrations:list

输出示例:

plaintext
1id | table_name | job_class_name | status | progress 2--------|----------------------------------|-----------------------------------------------|-----------|---------------------------------------------------------- 3main_1 | namespace_settings | UpdateRequireDpopForManageApiEndpointsToFalse | finished | 100.00% 4main_2 | resource_iteration_events | BackfillResourceIterationEventsNamespaceId | finalized | 100.00% 5main_3 | identities | DeleteTwitterIdentities | finalized | 100.00% 6main_4 | software_license_policies | BackfillLicensesOutsideSpdxCatalogue | finalized | 100.00% 7main_5 | security_policies | BackfillPipelineExecutionPoliciesMetadata | active | 42.50% (estimated time remaining: 5 minutes) 8ci_1 | ci_runners | MarkAdminBotRunnersAsHosted | finalized | 100.00% 9ci_2 | p_ci_build_trace_metadata | BackfillUpsertedCiBuildTraceMetadataProjectId | finalized | 100.00% 10ci_3 | ci_runners | BackfillOrganizationIdOnCiRunners | active | 78.30% (estimated time remaining: about 1 hour)

显示迁移详情#

要查看特定迁移的详细信息:

shell
sudo gitlab-rake gitlab:background_migrations:show[<migration_id>]

例如:

shell
sudo gitlab-rake gitlab:background_migrations:show[ci_1]

输出示例:

plaintext
1id | ci_1 2created_at | 2025-05-06 22:40:08 UTC 3updated_at | 2025-08-20 22:29:07 UTC 4min_value | 1 5max_value | 30 6batch_size | 1000 7sub_batch_size | 100 8interval | 120 9status | finalized 10job_class_name | MarkAdminBotRunnersAsHosted 11batch_class_name | PrimaryKeyBatchingStrategy 12table_name | ci_runners 13column_name | id 14job_arguments | [] 15total_tuple_count | 16pause_ms | 100 17max_batch_size | 18started_at | 2025-05-06 22:40:08 UTC 19on_hold_until | 20gitlab_schema | gitlab_ci 21finished_at | 2025-05-06 22:40:13 UTC 22queued_migration_version | 20250505095336 23min_cursor | 24max_cursor |

暂停迁移#

要暂停活跃的后台迁移:

shell
sudo gitlab-rake gitlab:background_migrations:pause[<migration_id>]

例如:

shell
sudo gitlab-rake gitlab:background_migrations:pause[main_85]

您只能暂停状态为 active的迁移。尝试暂停处于任何其他 状态的迁移都会导致错误。

恢复迁移#

要恢复已暂停的后台迁移:

shell
sudo gitlab-rake gitlab:background_migrations:resume[<migration_id>]

例如:

shell
sudo gitlab-rake gitlab:background_migrations:resume[main_85]

您只能恢复状态为 paused的迁移。尝试恢复处于任何其他 状态的迁移都会导致错误。

执行迁移#

此任务会在前台同步执行迁移。迁移会一直运行到完成 或失败。对于大型迁移,这可能会耗费大量时间,并可能影响数据库 性能。请尽可能在维护窗口期间使用此任务。

要立即执行特定的后台迁移:

shell
sudo gitlab-rake gitlab:background_migrations:execute[<migration_id>]

例如:

shell
sudo gitlab-rake gitlab:background_migrations:execute[ci_10]

输出示例:

plaintext
Are you sure you want to execute this migration? yes Executing background migration `ci_10`... Done.

该任务在执行前会提示确认。如果迁移未能完成,请使用 gitlab:background_migrations:show[<migration_id>] 检查迁移状态以了解更多详情。

执行所有迁移#

此任务会在前台同步执行所有未完成的迁移。这可能会耗费非常 长的时间,并显著影响数据库性能。请仅在计划内的维护 窗口期间使用此任务。即使个别迁移失败,该任务也会继续执行,但会在输出中报告失败情况。

要执行所有数据库中的所有未完成后台迁移:

shell
sudo gitlab-rake gitlab:background_migrations:execute_all

输出示例:

plaintext
1Are you sure you want to execute all unfinished migrations? yes 2[main] Executing 6 background migrations... 3[main_85]: Start. 4[main_85]: Done. 5[main_86]: Start. 6[main_86]: Done. 7[main_87]: Start. 8[main_87]: Done. 9[main_88]: Start. 10[main_88]: Done. 11[main_89]: Start. 12[main_89]: Done. 13[main_90]: Start. 14[main_90]: Done. 15[ci] Executing 3 background migrations... 16[ci_8]: Start. 17[ci_8]: Done. 18[ci_9]: Start. 19[ci_9]: Done. 20[ci_10]: Start. 21[ci_10]: Done.

该任务:

  • 在执行前提示确认。
  • 按 ID 顺序处理迁移。
  • 在每个迁移完成时报告其状态。
  • 即使某些迁移失败,也会继续处理剩余的迁移。

等待所有迁移完成#

要阻塞直到所有数据库中的所有未完成批处理后台迁移都已完成:

shell
sudo gitlab-rake gitlab:background_migrations:wait

输出示例:

plaintext
Waiting for batched background migrations to finish, checking every 30s... Still waiting on 1 batched background migration(s): Database: main active | BackfillPipelineExecutionPoliciesMetadata,security_policies,id,[] All batched background migrations have finished.

此任务适用于自动化场景,例如在开始下一次零停机升级之前,等待当前版本的迁移完成。与执行所有迁移不同,它本身不会运行迁移。它只会在调度器处理迁移期间轮询其状态。

该任务:

  • 检查每个已配置的数据库(main、ci 等)。
  • 轮询直到没有迁移处于 paused、active 或 finalizing 状态,然后以 0 退出。
  • 如果有任何迁移处于 failed 状态,则以非零状态退出,因为等待无法 清除该状态。请先按 解决失败的批处理后台迁移处理这些问题。

要控制该任务的轮询频率,请将 BATCHED_MIGRATIONS_WAIT_INTERVAL_SECONDS 环境变量设置为正整数(默认值为 30):

shell
sudo BATCHED_MIGRATIONS_WAIT_INTERVAL_SECONDS=60 gitlab-rake gitlab:background_migrations:wait

该任务没有内部超时。请从调用方限制总等待时间,例如使用 timeout 或作业截止时间。

该任务不会捕获瞬态数据库错误。如果因这类错误而失败,请重试整个任务。

检查待处理的数据库后台迁移#

为了分批更新数据库表,极狐GitLab 可以使用批处理后台迁移。这些迁移由 GitLab 开发者创建,并在升级时自动运行。但是,此类迁移的范围有限,仅用于帮助将某些 integer 数据库列迁移为 bigint,这是为了防止某些表出现整数溢出所必需的。

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

要减少完成这些迁移所需的时间,请增加可以在 background_migration 队列中处理作业的 Sidekiq 工作进程数量。

检查批处理后台迁移的状态#

您可以在极狐GitLab UI 中检查批处理后台迁移的状态,也可以直接查询数据库。在升级极狐GitLab 之前,所有迁移都必须处于 Finished 状态。

如果迁移未完成而您尝试升级极狐GitLab,可能会看到以下错误:

plaintext
Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':

如果遇到此错误,请查看相关选项,了解如何完成极狐GitLab 升级所需的批处理后台迁移。

从极狐GitLab UI 中检查#

先决条件:

  • 您必须具有实例的管理员访问权限。

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

  1. 在右上角,选择管理员。
  2. 在左侧边栏中,选择监控 > 后台迁移。
  3. 选择排队中或正在完成以查看未完成的迁移, 选择失败以查看失败的迁移。

如果某个迁移显示进度不可用,说明极狐GitLab 在迁移排队时无法估算表大小,因此无法计算百分比。如果状态为活跃,则迁移正在按预期运行。

从数据库中检查#

先决条件:

  • 您必须具有实例的管理员访问权限。

要直接查询数据库以了解批处理后台迁移的状态:

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

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

    sql
    1SELECT 2 job_class_name, 3 table_name, 4 column_name, 5 job_arguments 6FROM batched_background_migrations 7WHERE status NOT IN(3, 6);

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

shell
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:

    sql
    1SELECT 2 id, 3 job_class_name, 4 table_name, 5 column_name, 6 job_arguments 7FROM batched_background_migrations 8WHERE status NOT IN(3, 6);
  2. 运行以下查询,将 XX 替换为上一步中获取的 ID, 以查看迁移的状态:

    sql
    1SELECT 2 started_at, 3 finished_at, 4 finished_at - started_at AS duration, 5 min_value, 6 max_value, 7 batch_size, 8 sub_batch_size 9FROM batched_background_migration_jobs 10WHERE batched_background_migration_id = XX 11ORDER BY id DESC 12limit 10;
  3. 在几分钟内多次运行该查询,以确保没有新增行。 如果没有新增行,则迁移已暂停。

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

自动批次大小优化#

禁用已发布的功能可能存在风险。 有关更多详情,请参阅此功能的历史记录。

为了最大化批处理后台迁移的吞吐量(以每时间单位更新的元组数量衡量),批次大小会根据前几批完成所需的时间自动调整。

并行执行#

为了加快批处理后台迁移的执行速度,会同时执行两个迁移。

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

ruby
ApplicationSetting.update_all(database_max_running_batched_background_migrations: 4)

解决失败的批处理后台迁移#

如果批处理后台迁移失败,请修复并重试。如果迁移持续失败并报错,您可以:

修复并重试迁移#

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

失败的批处理后台迁移表。

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

先决条件:

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

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

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

先决条件:

  • 您必须具有实例的管理员访问权限。
  1. 在右上角,选择管理员。
  2. 在左侧边栏中,选择监控 > 后台迁移。
  3. 选择失败选项卡。这会显示失败的批处理后台迁移列表。
  4. 选择失败的批处理后台迁移,点击重试按钮()进行重试。

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

手动完成失败的迁移#

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

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

    plaintext
    1StandardError: An error has occurred, all later migrations canceled: 2 3Expected batched background migration for the given configuration to be marked as 4'finished', but it is 'active': 5 {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", 6 :table_name=>"push_event_payloads", 7 :column_name=>"event_id", 8 :job_arguments=>[["event_id"], 9 ["event_id_convert_to_bigint"]] 10 }
  2. 运行以下命令,将尖括号中的值替换为正确的参数:

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

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

    shell
    sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']

将失败的迁移标记为已完成#

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

在某些情况下后台迁移会失败:例如跨越过多版本升级,或数据库架构发生向后不兼容的更改。(有关示例,请参阅议题 393216)。失败的后台迁移会阻止进一步的应用升级。

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

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

ruby
1# Start the rails console 2 3connection = ApplicationRecord.connection # or Ci::ApplicationRecord.connection, depending on which DB was the migration scheduled 4 5Gitlab::Database::SharedModel.using_connection(connection) do 6 migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration( 7 Gitlab::Database.gitlab_schemas_for_connection(connection), 8 'BackfillUserDetailsFields', 9 :users, 10 :id, 11 [] 12 ) 13 14 # mark all jobs completed 15 migration.batched_jobs.update_all(status: Gitlab::Database::BackgroundMigration::BatchedJob.state_machine.states['succeeded'].value) 16 migration.update_attribute(:status, Gitlab::Database::BackgroundMigration::BatchedMigration.state_machine.states[:finished].value) 17end

同步运行所有后台迁移#

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

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

ruby
1# Start the rails console 2 3databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml 4 5Gitlab::Database.database_base_models.each do |database_name, model| 6 Gitlab::Database::SharedModel.using_connection(model.connection) do 7 Gitlab::Database::BackgroundMigration::BatchedMigration.with_status([:paused, :active]).find_each(batch_size: 100) do |migration| 8 puts "#{database_name}: Finalizing migration #{migration.job_class_name} (ID: #{migration.id})... " 9 Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize( 10 migration.job_class_name, 11 migration.table_name, 12 migration.column_name, 13 Gitlab::Json.parse(migration.job_arguments), 14 connection: model.connection 15 ) 16 puts("done!\n") 17 end 18 end 19end

查看批处理后台迁移日志#

在对批处理后台迁移进行故障排除时,您可以在多个位置查看详细的执行日志。

Sidekiq 日志#

Sidekiq 日志显示 Database::BatchedBackgroundMigrationWorker 作业的执行时间。这些日志显示作业执行情况,但不会指明正在运行的是哪个具体迁移。

应用日志#

要确定正在运行的是哪个批处理后台迁移,请查看应用日志。应用日志包含详细信息,包括:

  • 具体批处理后台迁移的类名(job_class_name)
  • 状态转换(pending、running 以及 succeeded 或 failed)

追踪迁移执行#

要追踪特定的批处理后台迁移:

  1. 在 Database::BatchedBackgroundMigrationWorker的 Sidekiq 日志条目中找到 correlation_id。
  2. 使用该 correlation_id 搜索应用日志,以查看详细的状态转换。

应用日志条目示例:

json
1{ 2 "severity": "INFO", 3 "time": "2025-08-27T22:52:07.806Z", 4 "meta.caller_id": "Database::BatchedBackgroundMigration::MainExecutionWorker", 5 "correlation_id": "74d0295cbe4bb6147230a7d481fb0f8a", 6 "message": "BatchedJob transition", 7 "batched_job_id": 725, 8 "previous_state": "pending", 9 "new_state": "running", 10 "batched_migration_id": 638, 11 "job_class_name": "BackfillSentNotificationsAfterPartition", 12 "job_arguments": [] 13}, 14{ 15 "severity": "INFO", 16 "time": "2025-08-27T22:52:14.293Z", 17 "meta.caller_id": "Database::BatchedBackgroundMigration::MainExecutionWorker", 18 "correlation_id": "74d0295cbe4bb6147230a7d481fb0f8a", 19 "message": "BatchedJob transition", 20 "batched_job_id": 725, 21 "previous_state": "running", 22 "new_state": "succeeded", 23 "batched_migration_id": 638, 24 "job_class_name": "BackfillSentNotificationsAfterPartition", 25 "job_arguments": [] 26}

检查待处理的高级搜索迁移#

Tier: 专业版,旗舰版

Offering: 私有化部署

本节仅在您启用了 Elasticsearch 集成时适用。大版本发布要求在当前版本的最新小版本中完成所有高级搜索迁移,然后才能进行大版本升级。您可以通过运行以下命令来查找待处理的迁移。

shell
sudo gitlab-rake gitlab:elastic:list_pending_migrations

如果已开启高级搜索索引,gitlab:check Rake 任务也会报告是否有任何高级搜索迁移待处理,以及有多少个。该检查仅报告状态,不会阻止升级,因此您必须阅读输出并根据结果采取行动。

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

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