GitLabで管理されているリポジトリの移動
GitLabで管理しているすべてのリポジトリを別のファイルシステムや別のサーバーに移動することができます。
GitLabインスタンス内のデータの移動
GitLab APIはGitリポジトリを移動するための推奨方法です:
- サーバー間
- 異なるストレージ間
- シングルノードからGitalyクラスタへ。
詳細については
-
Gitalyのための追加ストレージの設定。この例では、
storage1
とstorage2
という追加のストレージを設定します。 - API ドキュメントには、プロジェクトリポジトリのクエリと移動のスケジューリングのためのエンドポイントの詳細が記載されています。
- APIドキュメントでは、スニペットリポジトリの移動に関するクエリやスケジューリングのエンドポイントについて詳しく説明しています。
- APIドキュメントでは、グループリポジトリの移動のクエリとスケジューリングのエンドポイントを詳しく説明しています。 .
- Gitaly Clusterへのマイグレーション。
リポジトリの移動
GitLabリポジトリはプロジェクト、グループ、スニペットと関連付けることができます。これらのタイプはそれぞれ、リポジトリを移動するスケジュールを立てるための個別のAPIを持っています。GitLabインスタンス上のすべてのリポジトリを移動するには、それぞれのストレージに対してこれらのタイプの移動スケジュールを設定する必要があります。
gitaly_replicate_repository_direct_fetch
機能フラグを有効にする必要があります。各リポジトリは移動の間、読み取り専用になります。リポジトリは移動が完了するまで書き込みできません。
リポジトリを移動するには
-
ローカルとクラスターのすべてのストレージがGitLab インスタンスからアクセス可能であることを確認します。この例では、これらは
<original_storage_name>
と<cluster_storage_name>
です。 - リポジトリストレージの重み付けを設定し、新しいストレージがすべての新しいプロジェクトを受け取るようにします。これにより、マイグレーションが進行している間、既存のストレージに新しいプロジェクトが作成されなくなります。
- リポジトリ移動のスケジュールを設定します:
- Geoが有効な場合、すべてのリポジトリを再同期します。
すべてのプロジェクトを移動
APIを使用してすべてのプロジェクトを移動します:
-
API を使用して、ストレージ シャード上のすべてのプロジェクトのリポジトリ ストレージ移動をスケジュールします。例えば
curl --request POST --header "Private-Token: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/project_repository_storage_moves"
- API を使用して、直近のリポジトリ移動をクエリします。応答は次のいずれかを示します:
- 移動は正常に完了しました。
state
フィールドはfinished
です。 - 移動は進行中です。リポジトリの移動が正常に完了するまで、再度クエリを実行してください。
- 移動が失敗しました。ほとんどの失敗は一時的なもので、移動を再スケジュールすることで解決します。
- 移動は正常に完了しました。
-
移動が完了したら、API を使用してプロジェクトをクエリし、すべてのプロジェクトが移動したことを確認します。どのプロジェクトも、
repository_storage
フィールドが古いストレージに設定された状態で返されてはなりません。た と えばcurl --header "Private-Token: <your_access_token>" --header "Content-Type: application/json" \ "https://gitlab.example.com/api/v4/projects?repository_storage=<original_storage_name>"
あるいは、railsコンソールを使用して、すべてのプロジェクトが移動したことを確認します。railsコンソールで以下を実行します:
ProjectRepository.for_repository_storage('<original_storage_name>')
- 必要に応じて各ストレージで繰り返します。
すべてのスニペットを移動
すべてのスニペットを移動するには、APIを使用します:
-
ストレージ シャード上のすべてのスニペットに対してリポジトリ ストレージの移動をスケジュールします。例えば
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/snippet_repository_storage_moves"
-
直近のリポジトリの移動をクエリします。応答は次のいずれかを示します:
- 移動は正常に完了しました。
state
フィールドはfinished
です。 - 移動は進行中です。リポジトリの移動が正常に完了するまで、再度クエリを実行してください。
- 移動が失敗しました。ほとんどの失敗は一時的なもので、移動を再スケジュールすることで解決します。
- 移動は正常に完了しました。
-
移動が完了したら、Railsコンソールを使って全てのスニペットが移動したことを確認してください。元のストレージにスニペットが戻ってくることはありません。railsコンソールで以下を実行します:
SnippetRepository.for_repository_storage('<original_storage_name>')
- 必要に応じて各ストレージで繰り返します。
すべてのグループを移動
APIを使用してすべてのグループを移動します:
-
ストレージシャード上のすべてのグループのリポジトリストレージの移動をスケジュールします。例えば
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/group_repository_storage_moves"
-
直近のリポジトリの移動をクエリします。応答は次のいずれかを示します:
- 移動は正常に完了しました。
state
フィールドはfinished
です。 - 移動は進行中です。リポジトリの移動が正常に完了するまで、再度クエリを実行してください。
- 移動が失敗しました。ほとんどの失敗は一時的なもので、移動を再スケジュールすることで解決します。
- 移動は正常に完了しました。
-
移動が完了したら、Railsコンソールを使用して、すべてのグループが移動したことを確認します。グループが元のストレージに戻されることはありません。railsコンソールで以下を実行します:
GroupWikiRepository.for_repository_storage('<original_storage_name>')
- 必要に応じて各ストレージで繰り返します。
別のGitLabインスタンスへのマイグレーション
新しいGitLab環境にマイグレーションする場合などは、APIを使うという選択肢はありません:
- シングルノードのGitLabからスケールアウトしたアーキテクチャへ。
- 非公開データセンターのGitLabインスタンスからクラウドプロバイダーへ。
この文書の残りの部分では、すべてのリポジトリを/var/opt/gitlab/git-data/repositories
から/mnt/gitlab/repositories
にコピーする方法をいくつか見ていきます。
3つのシナリオを見てみましょう:
- ターゲットディレクトリが空の場合。
- ターゲットディレクトリにリポジトリの古いコピーが含まれています。
- 何千ものリポジトリに対処する方法。
/mnt/gitlab/repositories
ここで挙げた各アプローチは、ターゲットディレクトリ/mnt/gitlab/repositories
のデータを上書きする可能性があります。ソースとターゲットを混同しないでください。
すべてのケースで推奨されるアプローチ
GitalyまたはGitaly Clusterターゲットのいずれについても、GitLabのバックアップとリストア機能を使用する必要があります。Gitリポジトリは、GitalyによってGitLabサーバー上でデータベースとしてアクセス、管理、保存されます。rsync
のようなツールを使ってGitalyファイルに直接アクセスし、コピーすると、データ損失が発生する可能性があります。
- GitLab 13.3からは、複数のリポジトリを同時に処理することで、バックアップのパフォーマンスを向上させることができます。
- スキップ機能を使ってリポジトリだけのバックアップを作成できます。
Gitalyクラスターターゲットでは他の方法は使えません。
ターゲット・ディレクトリが空です:tar
パイプを使用してください。
Gitalyターゲット(Gitalyクラスターターゲットには推奨アプローチを使用)の場合、ターゲットディレクトリ/mnt/gitlab/repositories
が空の場合、最も簡単なのはtar
パイプを tar
使用することです。tar
この方法はオーバーヘッドが少なく、 tar
ほとんどの場合すでにシステムにインストールされています。
しかし、中断されたtar
パイプを再開することはできません。その場合、すべてのデータを再度コピーする必要があります。
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
tar -C /mnt/gitlab/repositories -xf -'
進捗状況を確認したい場合は、-xf
を-xvf
に置き換えてください。
tar
別のサーバーへのパイプ
Gitalyターゲット(Gitalyクラスターターゲットには推奨アプローチを使用)の場合、tar
パイプを使用して別のサーバーにデータをコピーすることもできます。git
のユーザーがgit@newserver
として新しいサーバーに SSH アクセスできる場合、SSH 経由でデータをパイプすることができます。
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
ssh git@newserver tar -C /mnt/gitlab/repositories -xf -'
もし、データを圧縮してからネットワークに流したい場合は、ssh
をssh -C
に置き換えてください。
ターゲット・ディレクトリにはリポジトリの古いコピーが含まれます。rsync
rsync
を使って Git データをマイグレーションすると、データの損失やリポジトリの破損を引き起こす可能性があります。rsync
これらの手順はレビュー中rsync
です。移行先のディレクトリにすでにリポジトリの一部または古いコピーが含まれている場合、tar
を使ってすべてのデータを再度コピーするのは無駄な場合があります。このシナリオでは、Gitaly ターゲットにはrsync
を使う方がよいでしょう(Gitaly Cluster ターゲットには推奨される方法を使用してください)。
このユーティリティは、すでにシステムにインストールされているか、apt
またはyum
を使用してインストール可能です。
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
/mnt/gitlab/repositories'
上記のコマンドの/.
は非常にインポートで、これがないとターゲット・ディレクトリのディレクトリ構造がおかしくなります。進捗を確認したい場合は、-a
を-av
に置き換えてください。
rsync
を別のサーバーにシングルコピーします。
rsync
を使って Git データをマイグレーションすると、データの損失やリポジトリの破損を引き起こす可能性があります。rsync
これらの手順はレビュー中rsync
です。Gitalyターゲットの場合(Gitalyクラスターターゲットの場合は推奨される方法を使用してください)、ソースシステムのgit
ユーザーがターゲットサーバーにSSHアクセスできる場合、rsync
を使用してネットワーク経由でリポジトリを送信することができます。
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
git@newserver:/mnt/gitlab/repositories'
何千もの Git リポジトリ: リポジトリごとにrsync
を使用します。
rsync
を使って Git データをマイグレーションすると、データの損失やリポジトリの破損を引き起こす可能性があります。これらの手順はレビュー中です。rsync
ジョブを開始するたびに、ジョブは実行されなければなりません:
- ソース・ディレクトリのすべてのファイルを検査します。
- ターゲットディレクトリのすべてのファイルを検査します。
- ファイルをコピーするかどうかを決定します。
ソースディレクトリやターゲットディレクトリに多くのコンテンツがある場合、rsync
GitLabサーバーにとって rsync
この起動フェーズがrsync
負担になることがあります rsync
。作業を小分けにして、一度にひとつのリポジトリを同期することで、GitLabrsync
サーバーの負担を rsync
減らすことができます。
rsync
に加えて、GNU Parallelsを使います。このユーティリティはGitLabには含まれていないので、apt
またはyum
を使って自分でインストールする必要があります。
このプロセスは
- ソースに存在しなくなったリポジトリをターゲットの場所にクリーンアップしません。
- Gitalyターゲットでのみ動作します。Gitalyクラスターターゲットには推奨アプローチを使用してください。
GitLabに知られているすべてのリポジトリのParallelsrsync
。
rsync
を使って Git データをマイグレーションすると、データの損失やリポジトリの破損を引き起こす可能性があります。これらの手順はレビュー中です。これは、一度に10個のrsync
プロセスでリポジトリを同期します。進捗を追跡して、必要に応じて転送を再開できるようにしています。
まず、git
が所有する新しいディレクトリを作成し、転送ログを格納します。転送手順を開始する前に、このディレクトリは空であり、その中にファイルを書き込んでいるのは私たちだけであると仮定します。
# Omnibus
sudo mkdir /var/opt/gitlab/transfer-logs
sudo chown git:git /var/opt/gitlab/transfer-logs
# Source
sudo -u git -H mkdir /home/git/transfer-logs
コピーしたいディレクトリのリストで、このプロセスに種をまきます。
# Omnibus
sudo -u git sh -c 'gitlab-rake gitlab:list_repos > /var/opt/gitlab/transfer-logs/all-repos-$(date +%s).txt'
# Source
cd /home/git/gitlab
sudo -u git -H sh -c 'bundle exec rake gitlab:list_repos > /home/git/transfer-logs/all-repos-$(date +%s).txt'
これで転送を開始できます。以下のコマンドは冪等であり、GNU Parallelsが実行したジョブの数はゼロに収束するはずです。収束しない場合は、all-repos-1234.txt
にリストされているリポジトリがコピーされる前に削除されたり名前が変更されたりしている可能性があります。
# Omnibus
sudo -u git sh -c '
cat /var/opt/gitlab/transfer-logs/* | sort | uniq -u |\
/usr/bin/env JOBS=10 \
/opt/gitlab/embedded/service/gitlab-rails/bin/parallel-rsync-repos \
/var/opt/gitlab/transfer-logs/success-$(date +%s).log \
/var/opt/gitlab/git-data/repositories \
/mnt/gitlab/repositories
'
# Source
cd /home/git/gitlab
sudo -u git -H sh -c '
cat /home/git/transfer-logs/* | sort | uniq -u |\
/usr/bin/env JOBS=10 \
bin/parallel-rsync-repos \
/home/git/transfer-logs/success-$(date +%s).log \
/home/git/repositories \
/mnt/gitlab/repositories
`
Parallelsrsync
最近アクティビティがあったリポジトリのみを対象とします。
rsync
を使って Git データをマイグレーションすると、データの損失やリポジトリの破損を引き起こす可能性があります。これらの手順はレビュー中です。2015-10-1 12:00 UTC 以降に開始した同期を既に一度行ったとします。その後に GitLab を使って変更されたリポジトリだけを同期したいかもしれません。SINCE
変数を使うと、rake
gitlab:list_repos
に最近のアクティビティがあるリポジトリだけを表示するように指定できます。
# Omnibus
sudo gitlab-rake gitlab:list_repos SINCE='2015-10-1 12:00 UTC' |\
sudo -u git \
/usr/bin/env JOBS=10 \
/opt/gitlab/embedded/service/gitlab-rails/bin/parallel-rsync-repos \
success-$(date +%s).log \
/var/opt/gitlab/git-data/repositories \
/mnt/gitlab/repositories
# Source
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:list_repos SINCE='2015-10-1 12:00 UTC' |\
sudo -u git -H \
/usr/bin/env JOBS=10 \
bin/parallel-rsync-repos \
success-$(date +%s).log \
/home/git/repositories \
/mnt/gitlab/repositories