バックグラウンドマイグレーションとアップグレード

  • GitLab 13.11でexecute_batched_migrations_on_scheduleというフラグで 導入されたバッチバックグラウンドマイグレーション。デフォルトでは無効になっています。
  • 機能フラグexecute_batched_migrations_on_schedule GitLab 13.12でデフォルトで有効
  • GitLabセルフマネージドインスタンスでは、GitLab管理者はこれを無効にすることができます。

リリースによっては、新しいバージョンにアップデートする前に異なるマイグレーションを完了させる必要があります。マイグレーションには2種類あります。これらは異なるので、GitLabをアップグレードする前に両方が完了していることを確認する必要があります:

これらのマイグレーションを完了するのに必要な時間を短縮するには、background_migration キュー内のジョブを処理できるSidekiq ワーカーの数を増やしてください。

バックグラウンドでの一括マイグレーション

データベースのテーブルをバッチで更新するために、GitLabはバッチバックグラウンドマイグレーションを使うことができます。これらのマイグレーションはGitLab開発者によって作成され、アップグレード時に自動的に実行されます。しかし、このようなマイグレーションは、integer データベースのカラムの一部をbigint にマイグレーションするのに役立つ程度に限定されています。 これは、いくつかのテーブルの整数オーバーフローを防ぐために必要です。

インストールによっては、アップグレードによって導入されたデータベースの変更を完了するために、GitLab 14.0を少なくとも1日実行する必要があるかもしれません。

バッチのバックグラウンドマイグレーションはSidekiqによって処理され、分離して実行されるため、マイグレーションが処理されている間もインスタンスはオペレーションを維持することができます。ただし、バッチのバックグラウンドマイグレーションが実行されている間、使用頻度の高い大規模インスタンスではパフォーマンスが低下する可能性があります。すべてのマイグレーションが完了するまで、Sidekiqのステータスを積極的に監視する必要があります。

バッチバックグラウンドマイグレーションのステータスの確認

GitLab UIで、またはデータベースに直接クエリすることで、バッチ化されたバックグラウンドマイグレーションのステータスを確認することができます。GitLabをアップグレードする前に、すべてのマイグレーションがFinished ステータスを持っている必要があります。

マイグレーションが終了していない状態でGitLabをアップグレードしようとすると、このエラーが表示されるかもしれません:

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

このエラーが表示された場合は、GitLabアップグレードに必要なバッチバックグラウンドマイグレーションを完了する方法のオプションをレビューしてください。

GitLab UIから

前提条件:

  • インスタンスへの管理者アクセス権が必要です。

バッチ化されたバックグラウンドマイグレーションのステータスを確認するには:

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. モニタリング] > [バックグラウンドマイグレーション]を選択します。
  4. 未完了のマイグレーションを表示するには[キュー中]または[ファイナライズ中]を選択し、失敗したマイグレーションを表示するには[失敗]を選択します。

データベースから

前提条件:

  • インスタンスへの管理者アクセス権が必要です。

バッチ化されたバックグラウンドマイグレーションのステータスをデータベースに直接クエリするには:

  1. インスタンスのインストール方法の指示に従って、psql プロンプトにログインします。例えば、Linuxパッケージインストールの場合はsudo gitlab-psql
  2. 不完全なバッチバックグランドマイグレーションの詳細を確認するには、psql セッションでこのクエリを実行します:

    SELECT
      job_class_name,
      table_name,
      column_name,
      job_arguments
    FROM batched_background_migrations
    WHERE status <> 3;
    

高度な機能の有効化または無効化

バッチバックグラウンドマイグレーションには、マイグレーションをカスタマイズしたり、マイグレーションを完全に一時停止したりできる機能フラグがあります。これらの機能フラグは、そのリスクを理解している上級ユーザーのみが無効にしてください。

GitLab 14.xでのバッチバックグラウンドマイグレーションの一時停止

caution
リリースされた機能を無効にする際にはリスクがあります。詳細については、各機能のバージョン履歴を参照してください。

進行中のバッチバックグラウンドマイグレーションを一時停止するには、バッチバックグラウンドマイグレーション機能を無効にします。この機能を無効にすると、現在のマイグレーションのバッチが完了し、機能が再び有効になるまで次のバッチの開始が待機します。

前提条件:

  • インスタンスへの管理者アクセス権が必要です。

以下のデータベースクエリを使用して、現在のバッチバックグラウンドマイグレーションの状態を確認します:

  1. 実行中のマイグレーションの ID を取得します:

    SELECT
     id,
     job_class_name,
     table_name,
     column_name,
     job_arguments
    FROM batched_background_migrations
    WHERE status <> 3;
    
  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 13.2 でoptimize_batched_migrationsというフラグで導入されました。デフォルトで有効。

caution
リリースされた機能を無効にするとリスクがあります。詳細はこの機能のバージョン履歴を参照してください。

フラグ: セルフマネジメントのGitLabでは、デフォルトでこの機能が利用可能です。この機能を非表示にするには、optimize_batched_migrations という機能フラグを無効にするよう管理者に依頼してください。GitLab.comでは、この機能は利用可能です。

バッチ化されたバックグラウンドマイグレーションのスループット(時間単位あたりの更新タプル数)を最大化するために、バッチサイズは前のバッチが完了するまでにかかった時間に基づいて自動的に調整されます。

並列実行

caution
リリースされた機能を無効にするとリスクがあります。詳細はこの機能のバージョン履歴を参照してください。

バッチ化されたバックグラウンドマイグレーションの実行を高速化するために、2つのマイグレーションが同時に実行されます。

GitLab RailsコンソールにアクセスできるGitLab管理者は、並行して実行されるバッチドバックグラウンドマイグレーションの数を変更できます:

ApplicationSetting.update_all(database_max_running_batched_background_migrations: 4)

失敗したバッチバックグラウンドマイグレーションの解決

バッチバックグラウンドマイグレーションが失敗した場合は、修正して再試行してください。マイグレーションがエラーで失敗し続ける場合は、次のいずれかを実行してください:

マイグレーションを修正して再試行します。

GitLab 14.3で導入されました

新しいバージョンのGitLabにアップグレードするには、失敗したバッチドバックグラウンドマイグレーションをすべて解決する必要があります。バッチドバックグラウンドマイグレーションのステータスを確認すると、いくつかのマイグレーションが失敗 したステータスでFailedタブに表示されることがあります:

failed batched background migrations table

バッチドバックグラウンドマイグレーションが失敗した原因を特定するには、失敗したエラーログを見るか、UIでエラー情報を見てください。

前提条件:

  • インスタンスへの管理者アクセス権が必要です。
  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. モニタリング] > [バックグラウンドマイグレーション]を選択します。
  4. 失敗しました]タブを選択します。失敗したバッチバックグラウンドマイグレーションのリストが表示されます。
  5. 失敗したマイグレーションを選択すると、マイグレーションパラメータと失敗したジョブが表示されます。
  6. 失敗したジョブ] で各IDを選択すると、ジョブが失敗した理由が表示されます。

GitLabのお客様であれば、サポートリクエストを開いてバッチバックグラウンドマイグレーションが失敗した理由をデバッグすることを検討してください。

問題を解決するには、失敗したマイグレーションを再試行することができます。

前提条件:

  • インスタンスへの管理者アクセス権が必要です。
  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. モニタリング] > [バックグラウンドマイグレーション]を選択します。
  4. 失敗しました]タブを選択します。失敗したバッチバックグラウンドマイグレーションのリストが表示されます。
  5. 再試行ボタン({retry})をクリックして、再試行する失敗したバッチバックグラウンドマイグレーションを選択します。

再試行されたバッチバックグラウンドマイグレーションを監視するには、定期的にバッチバックグラウンドマイグレーションのステータスを確認します。

失敗したマイグレーションを手動で終了します。

GitLab 14.1 で導入されました

エラーで失敗したバッチバックグラウンドマイグレーションを手動で終了するには、失敗したエラーログやデータベースの情報を使います:

From the failure error logs
  1. 失敗エラーログを表示し、次のようなAn error has occurred, all later migrations canceled エラーメッセージを探します:

    StandardError: An error has occurred, all later migrations canceled:
       
    Expected batched background migration for the given configuration to be marked as
    'finished', but it is '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>']
    

    例えば、前のステップからのマイグレーションを終了する場合:

    sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']
    
From the database
  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"]]

    コマンドは

    sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[["id"]\, ["id_convert_to_bigint"]]']
    

失敗したマイグレーションに終了マークを付けます。

caution
これらの手順を使用する前に、GitLabサポートに連絡してください。このアクションはデータロスを引き起こし、復旧が難しい方法でインスタンスを失敗させる可能性があります。

バックグラウンドマイグレーションが失敗するケースがあります: バージョンアップのジャンプが多すぎる場合、または互換性のないデータベーススキーマの変更が行われた場合です。(例については、イシュー 393216 を参照してください)。バックグラウンドマイグレーションが失敗すると、それ以降のアプリケーションのアップグレードができなくなります。

バックグラウンドマイグレーションがスキップしても “安全 “であると判断された場合、マイグレーションは手動で終了マークを付けることができます:

caution
先に進む前にバックアップを作成してください。
# 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

バックグラウンドマイグレーション

GitLab 13では、バックグラウンドマイグレーションはバッチされませんでした。GitLab 14以降では、このタイプのマイグレーションはバッチされたバックグラウンドマイグレーションに取って代わられました。

保留中のバックグラウンドマイグレーションをチェック

保留中のバッチ処理されていないバックグラウンドマイグレーションを確認するには、次の手順に従います:

Linux package (Omnibus)
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
Self-compiled (source)
cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'

失敗したバックグラウンドマイグレーションをチェックします。

失敗したバッチ以外のバックグラウンドマイグレーションを確認するには、次の手順に従います:

Linux package (Omnibus)

GitLab バージョン 14.10 以降の場合:

sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'

GitLabバージョン14.0-14.9の場合:

sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'
Self-compiled (source)

GitLab バージョン 14.10 以降の場合:

cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'

GitLabバージョン14.0-14.9の場合:

cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'

トラブルシューティング

バッチバックグラウンドマイグレーションが終了せず、データベースマイグレーションが失敗します。

GitLabバージョン14.2以降にアップデートすると、データベースのマイグレーションに失敗することがあります:

StandardError: An error has occurred, all later migrations canceled:

Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
  {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob",
   :table_name=>"push_event_payloads",
   :column_name=>"event_id",
   :job_arguments=>[["event_id"],
   ["event_id_convert_to_bigint"]]
  }

まず、14.2のバージョンごとのアップグレード手順に従っているか確認してください。もしそうであれば、手動でバックグラウンドマイグレーションを完了させることができます。)そうでない場合は、次のいずれかの方法を選択してください:

  1. 14.2+にアップデートする前に、必要なバージョンをロールバックしてアップグレードします。
  2. 現在のバージョンのままロールフォワードし、手動でバッチマイグレーションが正常に完了することを確認します。

ロールバックし、必要なアップグレードパスに従います。

  1. ロールバックし、以前にインストールしたバージョンを復元します。
  2. 14.2+にアップデートする前に、14.0.5または14.1にアップデートしてください。
  3. バッチ化されたバックグラウンドマイグレーションのステータスを確認し、再アップグレードを試みる前に、それらがすべて終了したとマークされていることを確認してください。アクティビティマークが残っている場合は、手動で終了させることができます。

アップグレードされたバージョンのマイグレーションをロールフォワードして終了します。

ダウンタイムを伴うデプロイの場合

バッチ化されたバックグラウンドマイグレーションをすべて実行するには、GitLabインストールのサイズによってはかなりの時間がかかります。

  1. データベースのバッチドバックグラウンドマイグレーションのステータスをチェックし、ステータスクエリが行を返さなくなるまで、適切な引数を指定して手動で実行してください。
  2. すべてのステータスが完了と表示されたら、インストールのマイグレーションを再実行してください。
  3. GitLabのアップグレードからデータベースのマイグレーションを完了します:

    sudo gitlab-rake db:migrate
    
  4. リコンフィギュアを実行します:

    sudo gitlab-ctl reconfigure
    
  5. インストールのアップグレードを終了します。
ダウンタイムなしのデプロイの場合

失敗したマイグレーションはデプロイ後のマイグレーションなので、アップグレードされたバージョンの実行中のインスタンスに残って、バッチ化されたバックグラウンドマイグレーションが終了するのを待つことができます。

  1. エラーメッセージからバッチ化されたバックグラウンドマイグレーションのステータスを確認し、それが終了したと表示されていることを確認します。まだアクティビティが残っている場合は、終了するまで待つか、手動で終了させてください。
  2. 残りのデプロイ後のマイグレーションが終了するように、インストールのマイグレーションを再実行します。

BackfillNamespaceIdForNamespaceRoute バッチマイグレーションジョブが失敗しました。

GitLab 14.8では、BackfillNamespaceIdForNamespaceRoute バッチドバックグラウンドマイグレーションジョブの完了に失敗することがあります。再試行すると、500 Server Error が返されます。このイシューはGitLab 14.9で解決されました。

このイシューを解決するには、GitLabを14.8から14.9にアップグレードしてください。GitLab 14.9にアップデートするまでは、失敗したバッチマイグレーションを無視することができます。

バックグラウンドマイグレーションがSidekiqキューに残っています。

caution
以下のオペレーションはGitLabのパフォーマンスを低下させる可能性があります。様々なデータベースやファイルの更新を行うSidekiqジョブが実行されます。

以下のチェックを実行してください。それがゼロ以外を返し、カウントが時間とともに減少しない場合は、このセクションの残りの手順に従ってください。

# For Linux package installations:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'

# For self-compiled installations:
cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'

特に、保留中のジョブが1000以上あり、ランタイム・メモリがオーバーフローしそうな場合は、以下のコマンドを再実行するのが安全です。

Linux package (Omnibus)
# Start the rails console
sudo gitlab-rails c

# Execute the following in the rails console
scheduled_queue = Sidekiq::ScheduledSet.new
pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
Self-compiled (source)
# Start the rails console
sudo -u git -H bundle exec rails RAILS_ENV=production

# Execute the following in the rails console
scheduled_queue = Sidekiq::ScheduledSet.new
pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }

バックグラウンドマイグレーションが’pending’状態で止まっている場合

caution
以下のオペレーションはGitLabのパフォーマンスを低下させる可能性があります。様々なデータベースやファイルの更新を行うSidekiqジョブが実行されます。
  • GitLab 14.2では、BackfillDraftStatusOnMergeRequests という名前のバックグラウンドマイグレーションが、インスタンスにマイグレーションのターゲットに一致するレコードがない場合に、アップグレードをまたいでペンディング状態で永久にスタックするイシューが導入されました。このスタックしたマイグレーションをクリーンアップするには、14.2.0のバージョン固有の説明を参照してください。
  • GitLab 14.4では、インスタンスにマイグレーションのターゲットに一致するレコードがない場合に、PopulateTopicsTotalProjectsCountCache というバックグラウンドマイグレーションがアップグレードに渡ってペンディング状態で永久にスタックするイシューが導入されました。このスタックしたマイグレーションをクリーンアップするには、14.4.0のバージョン固有の説明を参照してください。
  • GitLab 14.5では、インスタンスにマイグレーションのターゲットに一致するレコードがない場合に、UpdateVulnerabilityOccurrencesLocation というバックグラウンドマイグレーションがアップグレードに渡ってペンディング状態で永久にスタックするイシューが導入されました。このスタックしたマイグレーションをクリーンアップするには、14.5.0のバージョン固有の説明を参照してください。
  • GitLab 14.8では、PopulateTopicsNonPrivateProjectsCount という名前のバックグラウンドマイグレーションが、アップグレードをまたいでペンディング状態で永久にスタックするイシューが導入されました。このスタックしたマイグレーションをクリーンアップするには、14.8.0のバージョン固有の説明を参照してください。
  • GitLab 14.9では、インスタンスにマイグレーションのターゲットに一致するレコードがない場合に、ResetDuplicateCiRunnersTokenValuesOnProjects という名前のバックグラウンドマイグレーションがアップグレードに渡ってペンディング状態で永久にスタックするイシューが導入されました。このスタックしたマイグレーションをクリーンアップするには、14.9.0のバージョン固有の説明を参照してください。

pendingでスタックしている他のバックグラウンドマイグレーションについては、以下のチェックを実行してください。これがゼロ以外を返し、カウントが時間経過とともに減少しない場合は、このセクションの残りの手順に従ってください。

# For Linux package installations:
sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'

# For self-compiled installations:
cd /home/git/gitlab
sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'

保留状態を解除するために、これらのマイグレーションを再試行することは安全です:

Linux package (Omnibus)
# Start the rails console
sudo gitlab-rails c

# Execute the following in the rails console
Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
  puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
  result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
  puts "Result: #{result}"
end
Self-compiled (source)
# Start the rails console
sudo -u git -H bundle exec rails RAILS_ENV=production

# Execute the following in the rails console
Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
  puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
  result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
  puts "Result: #{result}"
end