- 문제 해결 명령
- 프로젝트 불일치로 인한 가져오기 실패
- 가져온 프로젝트에서 누락된 사용자
- 대형 리포지터리에 대한 가져오기 우회 방법
- 내보내기 단계 매뉴얼 실행
e.send(:exporter_name).send(:save)
를 통해 내보내기 디렉터리을 실행하세요.- REST API를 사용한 가져오기가 그룹 액세스 토큰을 사용할 때 실패하는 문제 해결
- 성능 문제 해결
프로젝트 이주 파일 이주 문제 해결
migrating projects using file exports에 문제가 있는 경우, 아래 가능한 해결방법을 참조하십시오.
문제 해결 명령
JID를 사용하여 가져오기 상태 및 추가 로그에 대한 정보를 찾으려면 Rails 콘솔을 사용하십시오:
Project.find_by_full_path('group/project').import_state.slice(:jid, :status, :last_error)
> {"jid"=>"414dec93f941a593ea1a6894", "status"=>"finished", "last_error"=>nil}
# 로그
grep JID /var/log/gitlab/sidekiq/current
grep "Import/Export error" /var/log/gitlab/sidekiq/current
grep "Import/Export backtrace" /var/log/gitlab/sidekiq/current
tail /var/log/gitlab/gitlab-rails/importer.log
프로젝트 불일치로 인한 가져오기 실패
만약 내보낸 프로젝트와 프로젝트 가져오기 간에 인스턴스 러너 활성화가 일치하지 않으면 프로젝트 가져오기에 실패합니다. 이슈 276930를 검토하고 다음 중 하나를 수행하세요:
- 원본 및 대상 프로젝트에서 인스턴스 러너를 활성화합니다.
- 프로젝트를 가져올 때 부모 그룹에서 인스턴스 러너를 비활성화합니다.
가져온 프로젝트에서 누락된 사용자
가져온 프로젝트에 사용자가 누락된 경우, 사용자 기여 유지 요구 사항을 참조하십시오.
사용자가 누락된 일반적인 이유는 사용자의 공개 이메일 설정이 구성되어 있지 않을 수 있습니다. 이 문제를 해결하려면 사용자에게 GitLab UI를 사용하여 이 설정을 구성하도록 요청하십시오.
매뉴얼 구성이 불가능한 경우, 모든 사용자 프로필을 공개 이메일 주소를 사용하도록 설정할 수 있습니다. 이를 위해 Rails 콘솔을 사용하십시오:
User.where("public_email IS NULL OR public_email = '' ").find_each do |u|
next if u.bot?
puts "#{u.username}의 현재 비어 있는 공개 이메일을 #{u.email}로 설정 중..."
u.public_email = u.email
u.save!
end
대형 리포지터리에 대한 가져오기 우회 방법
최대 가져오기 크기 제한으로 인해 가져오기가 성공적으로 이루어지지 않을 수 있습니다. 가져오기 제한을 변경할 수 없는 경우, 여기 나열된 우회 방법 중 하나를 시도해볼 수 있습니다.
우회 옵션 1
임시로 리포지터리 크기를 줄이는 다음의 로컬 워크플로우를 사용하여 다시 가져오기를 시도할 수 있습니다:
-
내보낸 파일에서 임시 작업 디렉터리를 생성합니다:
EXPORT=<확장자 없는 파일 이름> mkdir "$EXPORT" tar -xf "$EXPORT".tar.gz --directory="$EXPORT"/ cd "$EXPORT"/ git clone project.bundle # 나중에 가져올 수 있는 파일이 생성되는 것을 방지 mv project.bundle ../"$EXPORT"-original.bundle mv ../"$EXPORT".tar.gz ../"$EXPORT"-original.tar.gz git switch --create smaller-tmp-main
-
리포지터리 크기를 줄이기 위해
smaller-tmp-main
브랜치에서 작업합니다: 크기가 큰 파일 식별 및 삭제하거나 대화식 리베이스 및 수정을 통해 커밋 수를 줄입니다.# .git/objects/pack/ 파일 크기를 줄입니다 cd project git reflog expire --expire=now --all git gc --prune=now --aggressive # 가져올 수 있는 파일을 준비합니다 git bundle create ../project.bundle <기본-브랜치-이름> cd .. mv project/ ../"$EXPORT"-project cd .. # 가져올 수 있는 파일을 다시 생성합니다 tar -czf "$EXPORT"-smaller.tar.gz --directory="$EXPORT"/ .
- 새로운, 더 작은 파일을 GitLab에 가져옵니다.
- 원본 리포지터리의 전체 복제에서
git remote set-url origin <새 URL>
및git push --force --all
을 사용하여 가져오기를 완료합니다. - 가져온 리포지터리의 브랜치 보호 규칙 및
기본 브랜치를 업데이트하고,
임시
smaller-tmp-main
브랜치 및 지역 임시 데이터를 삭제합니다.
우회 옵션 2
모든 변경사항을 한 번에 푸시하려는 대신, 이 방법은 다음을 수행합니다:
- 프로젝트 가져오기와 Git 리포지터리 가져오기를 분리합니다.
- 리포지터리를 GitLab에 점진적으로 푸시합니다.
- 마이그레이션할 리포지터리의 로컬 복제본을 만듭니다. 나중에 이 복제본을 프로젝트 내보내기 밖에서 푸시합니다.
-
내보내기를 다운로드하고
project.bundle
(Git 리포지터리를 포함하는 파일)을 제거합니다:tar -czvf new_export.tar.gz --exclude='project.bundle' @old_export.tar.gz
- Git 리포지터리 없이 내보내기를 가져옵니다. 리포지터리 없이 가져올 것인지 확인하는 메시지가 표시됩니다.
-
적절한 원본을 추가한 후 이 bash 스크립트를 파일로 저장하고 실행하십시오.
#!/bin/sh # 가정: # - GitLab 위치: "origin" # - 기본 브랜치: "main" # - 총 크기를 500MB의 단위로 분할하여 시간 초과가 발생하는 경우 더 작은 단위로 줄이십시오. git gc SIZE=$(git count-objects -v 2> /dev/null | grep size-pack | awk '{print $2}') # 보수적으로... 및 2GB씩 푸시를 시도합니다 # (이는 각 커밋이 동일한 크기임을 가정하므로 잘못됨) BATCHES=$(($SIZE / 500000)) TOTAL_COMMITS=$(git rev-list --count HEAD) if (( BATCHES > TOTAL_COMMITS )); then BATCHES=$TOTAL_COMMITS fi INCREMENTS=$(( ($TOTAL_COMMITS / $BATCHES) - 1 )) for (( BATCH=BATCHES; BATCH>=1; BATCH-- )) do COMMIT_NUM=$(( $BATCH - $INCREMENTS )) COMMIT_SHA=$(git log -n $COMMIT_NUM --format=format:%H | tail -1) git push -u origin ${COMMIT_SHA}:refs/heads/main done git push -u origin main git push -u origin --all git push -u origin --tags
내보내기 단계 매뉴얼 실행
일반적으로 웹 인터페이스 또는 API를 통해 프로젝트를 내보냅니다. 이러한 방법을 사용하여 내보내기가 충분한 정보를 제공하지 않고 실패하는 경우, Rails 콘솔 세션을 열고 정의된 모든 내보내기를 순환 실행합니다. 여러분이 볼 수 있도록 각 명령을 한 줄씩 실행하고 전체 블록을 붙여넣지 마십시오.
# 사용자는 내보내기 권한을 가지고 있어야 합니다
u = User.find_by_username('someuser')
p = Project.find_by_full_path('some/project')
e = Projects::ImportExport::ExportService.new(p,u)
e.send(:version_saver).send(:save)
e.send(:repo_saver).send(:save)
e.send(:avatar_saver).send(:save)
e.send(:project_tree_saver).send(:save)
e.send(:uploads_saver).send(:save)
e.send(:wiki_repo_saver).send(:save)
e.send(:lfs_saver).send(:save)
e.send(:snippets_repo_saver).send(:save)
e.send(:design_repo_saver).send(:save)
e.send(:exporter_name).send(:save)
를 통해 내보내기 디렉터리을 실행하세요.
내보내기 가능한(p) 및 공유된(p.import_export_shared) 사항을 사용하여, 다음 줄은 다음과 유사한 내보내기 경로를 보여줍니다: /var/opt/gitlab/gitlab-rails/shared/tmp/gitlab_exports/@hashed/49/94/4994….
s = Gitlab::ImportExport::Saver.new(exportable: p, shared:p.import_export_shared)
# 업로드를 시도하려면:
s.send(:compress_and_save)
s.send(:save_upload)
프로젝트가 성공적으로 업로드된 후, 내보낸 프로젝트는 /var/opt/gitlab/gitlab-rails/uploads/-/system/import_export_upload/export_file/
에 .tar.gz
파일로 위치합니다.
REST API를 사용한 가져오기가 그룹 액세스 토큰을 사용할 때 실패하는 문제 해결
그룹 액세스 토큰은 프로젝트 또는 그룹 가져오기 작업에 대해 작동하지 않습니다. 그룹 액세스 토큰이 가져오기를 시작하면 다음 메시지와 함께 가져오기가 실패합니다:
Error adding importer user to Project members.
Validation failed: User project bots cannot be added to other groups / projects
Import REST API를 사용하려면 개인 액세스 토큰과 같은 일반 사용자 계정 자격 증명을 전달하세요.
성능 문제 해결
다음의 내보내기/가져오기를 사용하여 현재 성능 문제를 읽어보세요.
OOM 오류
메모리 부족(OOM) 오류는 보통 Sidekiq Memory Killer에 의해 발생합니다:
SIDEKIQ_MEMORY_KILLER_MAX_RSS = 2000000
SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS = 3000000
SIDEKIQ_MEMORY_KILLER_GRACE_TIME = 900
가져오기 상태가 started
이고, 다음과 같은 Sidekiq 로그가 메모리 문제를 나타냅니다:
WARN: Work still in progress <struct with JID>
타임아웃
시간초과 오류는 Gitlab::Import::StuckProjectImportJobsWorker
가 프로세스를 실패로 표시할 때 발생합니다:
module Gitlab
module Import
class StuckProjectImportJobsWorker
include Gitlab::Import::StuckImportJob
# ...
end
end
end
module Gitlab
module Import
module StuckImportJob
# ...
IMPORT_JOBS_EXPIRATION = 15.hours.to_i
# ...
def perform
stuck_imports_without_jid_count = mark_imports_without_jid_as_failed!
stuck_imports_with_jid_count = mark_imports_with_jid_as_failed!
track_metrics(stuck_imports_with_jid_count, stuck_imports_without_jid_count)
end
# ...
end
end
end
막힌 가져오기 작업을 실패로 표시했습니다. JID: xyz
+-----------+ +-----------------------------------+
|내보내기 작업|--->| 모든 프로젝트 모델에서 ActiveRecord `as_json` 및 |
+-----------+ | `to_json`을 호출합니다 |
+-----------------------------------+
+-----------+ +-----------------------------------+
|가져오기 작업|--->| 메모리에 모든 JSON을 로드한 후, |
+-----------+ | 일괄적으로 DB에 삽입합니다 |
+-----------------------------------+
문제 및 해결책
문제 | 가능한 해결책 |
---|---|
데이터베이스에서 모델을로드/덤프하는 JSON 처리 속도가 느림 | 작업 분할 |
일괄 내보내기 | |
SQL 최적화 | |
ActiveRecord 콜백에서 이탈 (어려움)
| |
메모리 사용량이 높음 (일부 분석도 참조) | 메모리를 덜 사용하는 DB 커밋 최적 지점 |
Netflix Fast JSON API가 도움이 될 수 있음 | |
디스크로의 일괄적인 읽기/쓰기 및 모든 SQL |
임시 해결책
성능 문제가 해결되지 않은 동안, 대형 프로젝트를 가져올 때 대처할 수 있는 프로세스가 있습니다. 대형 프로젝트의 경우 전경 가져오기를 사용하세요. (인프라 트래커의 가져오기 템플릿을 사용합니다: infrastructure tracker)