GitLab이 관리하는 리포지터리 이전
GitLab이 관리하는 모든 리포지터리를 다른 파일 시스템이나 다른 서버로 이동할 수 있습니다.
GitLab 인스턴스에서 데이터 이동
GitLab API는 Git 리포지터리를 이동하는 권장 방법입니다:
- 서버 간.
- 서로 다른 리포지터리 간.
- 단일 노드 Gitaly에서 Gitaly 클러스터로.
자세한 정보는 다음을 참조하세요:
-
Gitaly에 대한 추가 리포지터리 구성. 이 예제에서는
storage1
및storage2
라고 하는 추가 리포지터리를 구성합니다. - API 문서는 프로젝트 리포지터리 이동에 대한 엔드포인트를 자세히 설명합니다.
- API 문서는 스니펫 리포지터리 이동에 대한 엔드포인트를 자세히 설명합니다.
- API 문서는 그룹 리포지터리 이동에 대한 엔드포인트를 자세히 설명합니다.
- Gitaly 클러스터로 마이그레이션.
리포지터리 이동
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
의 데이터를 덮어쓰거나 덮어쓰게 될 수 있습니다.
원본과 대상을 혼동하지 마세요.모든 경우에 권장하는 접근 방식
Gitaly 또는 Gitaly 클러스터 대상의 경우, GitLab 백업 및 복원 기능을 사용해야 합니다. Git 리포지터리는 Gitaly을 통해 데이터베이스로써 GitLab 서버에서 액세스, 관리 및 저장됩니다. rsync
와 같은 도구를 사용하여 Gitaly 파일에 직접 액세스하면 데이터 손실이 발생할 수 있습니다.
- GitLab 13.3부터 여러 리포지터리를 동시에 처리하여 백업 성능을 향상시킬 수 있습니다.
- 백업에서는 스킵 기능을 사용하여 리포지터리만 백업할 수 있습니다.
Gitaly 클러스터 타깃에는 다른 방법이 작동하지 않습니다.
대상 디렉터리가 비어 있는 경우: tar
파이프 사용
Gitaly 타깃의 경우(지탈리 클러스터 타깃의 경우 권장된 접근 방식 사용), 대상 디렉터리 /mnt/gitlab/repositories
가 비어 있는 경우 가장 간단한 방법은 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 타깃의 경우(지탈리 클러스터 타깃의 경우 권장된 접근 방식 사용), 데이터를 다른 서버로 복사하기 위해 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 -'
네트워크를 통해 데이터를 압축하려면(이 경우 CPU 사이클이 발생함) ssh
를 ssh -C
로 바꿀 수 있습니다.
대상 디렉터리에 오래된 복사본이 있는 경우: rsync
사용
rsync
를 사용하여 Git 데이터를 이관하면 데이터 손실과 리포지터리 손상이 발생할 수 있습니다.
이 지침은 검토 중입니다.대상 디렉터리에 데이터의 부분적이거나 오래된 복사본이 이미 있는 경우 모든 데이터를 tar
로 다시 복사하는 것은 낭비일 수 있습니다. 이러한 시나리오에서는 Gitaly 타깃의 경우 권장된 접근 방식를 사용하고, rsync
를 사용하는 것이 좋습니다(지탈리 클러스터 타깃의 경우).
이 유틸리티는 시스템에 이미 설치되어 있거나 apt
또는 yum
을 사용하여 설치할 수 있습니다.
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
/mnt/gitlab/repositories'
위 명령어에서 /.
는 매우 중요하며, 이것이 없으면 대상 디렉터리에 잘못된 디렉터리 구조가 만들어질 수 있습니다.
진행 상황을 보려면 -a
를 -av
로 바꿉니다.
다른 서버로의 단일 rsync
rsync
를 사용하여 Git 데이터를 이관하면 데이터 손실과 리포지터리 손상이 발생할 수 있습니다.
이 지침은 검토 중입니다.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
사용은 데이터 손실 및 리포지터리 손상을 일으킬 수 있습니다.
이 지침은 검토 중입니다.rsync
작업을 시작할 때마다 다음을 수행해야 합니다.
- 소스 디렉터리의 모든 파일을 검사합니다.
- 대상 디렉터리의 모든 파일을 검사합니다.
- 파일을 복사해야 하는지 여부를 결정합니다.
소스 또는 대상 디렉터리에 많은 내용이 있는 경우 rsync
의 시작 단계는 GitLab
서버에 부담이 될 수 있습니다. rsync
의 작업 부하를 줄이려면 작업을 작은 조각으로 나누고 한 번에 하나의 리포지터리를 동기화할 수 있습니다.
rsync
외에도 GNU Parallel을 사용합니다.
이 유틸리티는 GitLab에 포함되어 있지 않으므로 apt
또는 yum
을 사용하여 직접 설치해야 합니다.
이 프로세스는 다음과 같습니다.
- 소스에 없어진 대상 위치의 리포지터리를 정리하지 않습니다.
- Gitaly 대상에만 작동합니다. Gitaly Cluster 대상의 경우 권장된 방법을 사용하십시오.
GitLab에서 알려진 모든 리포지터리에 대한 병렬 rsync
rsync
사용은 데이터 손실 및 리포지터리 손상을 일으킬 수 있습니다.
이 지침은 검토 중입니다.이 명령은 한 번에 10개의 rsync
프로세스로 리포지터리를 동기화합니다. 전송이 필요한 경우
재시작할 수 있도록 진행 상황을 추적합니다.
먼저 git
이 소유한 새 디렉터리를 만들어 전송
로그를 보관하는데 사용합니다. 전송 프로시저를 시작하기 전에 디렉터리가 비어 있고
해당 디렉터리에 파일을 쓰는 유일한 사용자라고 가정합니다.
# Omnibus
sudo mkdir /var/opt/gitlab/transfer-logs
sudo chown git:git /var/opt/gitlab/transfer-logs
# 소스
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'
# 소스
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'
이제 전송을 시작할 수 있습니다. 아래 명령은 idempotent하며
GNU Parallel에 의해 수행되는 작업 수는 0에 수렴해야 합니다. 그렇지 않은 경우 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
'
# 소스
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
`
최근 활동이 있는 리포지터리에 대해서만 병렬 rsync
rsync
사용은 데이터 손실 및 리포지터리 손상을 일으킬 수 있습니다.
이 지침은 검토 중입니다.이미 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
# 소스
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