- 문제 해결 명령어
- 프로젝트가 불일치로 인해 가져오지 못함
- 가져온 프로젝트에서 누락된 사용자
- 대규모 리포지토리에 대한 가져오기 우회 방법
- 수동으로 내보내기 단계 실행
e.send(:exporter_name).send(:save)
를 사용하여 내보내기 목록을 계속 진행- 그룹 액세스 토큰을 사용할 때 REST API로 가져오기가 실패
- 오류:
PG::QueryCanceled: ERROR: canceling statement due to statement timeout
- 오류:
command exited with error code 15 and Unable to save [FILTERED] into [FILTERED]
- 성능 문제 해결
파일 내보내기 프로젝트 마이그레이션 문제 해결
파일 내보내기를 사용하여 프로젝트를 마이그레이션하는 데 문제가 있는 경우, 아래의 가능한 솔루션을 참조하세요.
문제 해결 명령어
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 "Setting #{u.username}'s currently empty public email to #{u.email}…"
u.public_email = u.email
u.save!
end
대규모 리포지토리에 대한 가져오기 우회 방법
최대 가져오기 크기 제한은 가져오기가 성공적으로 수행되는 것을 방지할 수 있습니다. 가져오기 제한을 변경할 수 없는 경우, 여기 나열된 우회 방법 중 하나를 시도해 볼 수 있습니다.
우회 방법 옵션 1
다음 로컬 워크플로우를 사용하여 다시 가져오기 시도의 위해 리포지토리 크기를 임시로 줄일 수 있습니다:
-
내보내기에서 임시 작업 디렉터리를 만듭니다:
EXPORT=<filename-without-extension> 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 <default-branch-name> cd .. mv project/ ../"$EXPORT"-project cd .. # 가져올 수 있는 파일을 재생성합니다 tar -czf "$EXPORT"-smaller.tar.gz --directory="$EXPORT"/ .
- 이 새롭고 작은 파일을 GitLab에 가져옵니다.
- 원본 리포지토리의 전체 클론에서,
git remote set-url origin <new-url> && git push --force --all
를 사용하여 가져오기를 완료합니다. - 가져온 리포지토리의
브랜치 보호 규칙과
기본 브랜치를 업데이트하고,
임시 브랜치인
smaller-tmp-main
과 로컬 임시 데이터를 삭제합니다.
해결책 옵션 2
참고:
이 해결책은 LFS 객체를 고려하지 않습니다.
모든 변경 사항을 한 번에 푸시하려고 시도하기보다는 이 해결책이:
- 프로젝트 가져오기와 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의 청크로 푸시를 시도합니다 (총 크기를 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)
를 사용하여 내보내기 목록을 계속 진행
다음 줄은 /var/opt/gitlab/gitlab-rails/shared/tmp/gitlab_exports/@hashed/49/94/4994….와 유사한 export_path를 보여줘야 합니다.
s = Gitlab::ImportExport::Saver.new(exportable: p, shared: p.import_export_shared, user: u)
GitLab 17.0 이전에는 user
매개변수가 지원되지 않았습니다. 위의 내용에서 오류가 발생하거나 user
인수를 제공해야 하는지 확실하지 않은 경우, 다음 확인을 사용하세요:
Gitlab::ImportExport::Saver.instance_method(:initialize).parameters.include?([:keyreq, :user]) # 앞선 확인이 false를 반환하면 user 인수를 생략하세요: 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
가져오기 REST API를 사용하려면, 개인 액세스 토큰과 같은 일반 사용자 계정 자격 증명을 전달하세요.
오류: PG::QueryCanceled: ERROR: canceling statement due to statement timeout
일부 마이그레이션은 오류: PG::QueryCanceled: ERROR: canceling statement due to statement timeout
와 함께 시간 초과가 발생할 수 있습니다. 이 문제를 피하는 한 가지 방법은 마이그레이션 배치 크기를 줄이는 것입니다. 이는 마이그레이션이 시간 초과될 가능성을 낮추지만, 마이그레이션을 느리게 만듭니다.
배치 크기를 줄이려면 기능 플래그가 활성화되어야 합니다. 자세한 내용은 문제 456948를 참조하세요.
오류: command exited with error code 15 and Unable to save [FILTERED] into [FILTERED]
파일 내보내기를 사용하여 프로젝트를 마이그레이션할 때 command exited with error code 15 and Unable to save [FILTERED] into [FILTERED]
라는 오류가 로그에 나타날 수 있습니다. 이 오류가 발생하면:
- 파일 내보내기를 할 때 오류를 무시해도 안전합니다. GitLab은 종료된 명령을 재시도합니다.
- 파일 가져오기를 할 때는 가져오기를 다시 시도해야 합니다. GitLab은 가져오기를 자동으로 다시 시도하지 않습니다.
성능 문제 해결
아래 Import/Export를 사용하여 현재 성능 문제를 읽어보세요.
OOM 오류
메모리 부족(Out of Memory, 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
막힌 가져오기 작업을 실패로 표시했습니다. JIDs: xyz
+-----------+ +-----------------------------------+
|내보내기 작업 |--->| 모든 프로젝트 모델에 대해 ActiveRecord `as_json`과 |
+-----------+ | `to_json`을 호출합니다. |
+-----------------------------------+
+-----------+ +-----------------------------------+
|가져오기 작업 |--->| 모든 JSON을 메모리에 로드한 다음 |
+-----------+ | 배치로 DB에 삽입합니다. |
+-----------------------------------+
문제 및 해결책
문제 | 가능한 해결책 |
---|---|
느린 JSON 데이터베이스에서 모델을 로드/덤프 | 작업자 나누기 |
배치 내보내기 | |
SQL 최적화 | |
ActiveRecord 콜백에서 벗어나기 (어려움) |
|
고메모리 사용 (자세한 분석 참조) | 메모리를 적게 사용하는 DB 커밋 적정점 |
Netflix Fast JSON API 도움이 될 수 있음 | |
디스크에 대한 배치 읽기/쓰기 및 모든 SQL |
임시 해결책
성능 문제를 해결하지 못하는 동안, 대규모 프로젝트 수입을 우회하는 프로세스가 있습니다:
고객을 위한 대규모 프로젝트의 전경 가져오기.
(인프라 추적기의 가져오기 템플릿 사용)