Geo 복제 문제 해결

Tier: Premium, Ultimate Offering: Self-managed

PostgreSQL 데이터베이스 복제 오류 수정

다음 섹션에서는 복제 오류 메시지(Database replication working? ... no로 표시됨)를 수정하기 위한 문제 해결 단계를 설명합니다.
geo:check 출력을 참조하세요.
이곳의 지침은 주로 단일 노드 Geo Linux 패키지 배포를 가정하며, 다른 환경에 맞게 조정될 필요가 있습니다.

비활성 복제 슬롯 제거

복제 슬롯은 복제 클라이언트(보조 사이트)가 슬롯에 연결된 상태에서 연결이 끊어지면 ‘비활성’으로 표시됩니다.
비활성 복제 슬롯은 WAL 파일을 보존하게 되며, 클라이언트가 다시 연결될 때 해당 슬롯으로 전송되고 슬롯이 다시 활성화됩니다.
보조 사이트가 다시 연결할 수 없는 경우, 다음 단계를 사용하여 해당 비활성 복제 슬롯을 제거합니다:

  1. Geo 기본 사이트의 데이터베이스 노드에서 PostgreSQL 콘솔 세션 시작:

    sudo gitlab-psql -d gitlabhq_production
    

    참고:
    gitlab-rails dbconsole을 사용하는 것은 작동하지 않습니다. 복제 슬롯 관리는 슈퍼유저 권한이 필요하기 때문입니다.

  2. 복제 슬롯을 확인하고 비활성 슬롯을 제거합니다:

    SELECT * FROM pg_replication_slots;
    

    activef인 슬롯은 비활성입니다.

    • 이 슬롯이 활성화되어야 한다면, 해당 슬롯을 사용하는 보조 사이트의 PostgreSQL 로그를 확인하여 복제가 실행되지 않는 이유를 확인합니다.
    • 슬롯을 더 이상 사용하지 않거나(예: Geo가 비활성화된 경우), 보조 사이트가 더 이상 연결할 수 없는 경우, PostgreSQL 콘솔 세션을 사용하여 제거합니다:

      SELECT pg_drop_replication_slot('<name_of_inactive_slot>');
      
  3. 더 이상 필요하지 않은 경우 해당 Geo 사이트 제거 단계를 따르거나, 복제 프로세스 재시작 단계를 진행하여 복제 슬롯을 올바르게 재생성합니다.

메시지: WARNING:oldest xmin is far in the pastpg_wal 크기 증가

복제 슬롯이 비활성 상태인 경우, 슬롯에 해당하는 pg_wal 로그는 영구적으로 예약됩니다
(또는 슬롯이 다시 활성화될 때까지). 이로 인해 지속적인 디스크 사용량 증가가 발생하며, 다음과 같은 메시지가
PostgreSQL 로그에 반복적으로 나타납니다:

WARNING:oldest xmin is far in the past  
HINT: Close open transactions soon to avoid wraparound problems.  
You might also need to commit or roll back old prepared transactions, or drop stale replication slots.  

이를 수정하기 위해서는 비활성 복제 슬롯 제거 단계를 따르고 복제를 재시작해야 합니다.

메시지: ERROR: replication slots can only be used if max_replication_slots > 0?

이는 max_replication_slots PostgreSQL 변수가 기본 데이터베이스에 설정되어야 함을 의미합니다.
이 설정은 기본값이 1입니다. 더 많은 보조 사이트가 있는 경우 이 값을 늘려야 할 수 있습니다.

PostgreSQL이 작동하려면 반드시 재시작해야 합니다. 자세한 내용은
PostgreSQL 복제 설정 가이드를 참조하세요.

메시지: replication slot "geo_secondary_my_domain_com" does not exist

이 오류는 PostgreSQL에 해당 이름의 secondary 사이트에 대한 복제 슬롯이 없을 때 발생합니다:

FATAL:  WAL 스트리밍을 시작할 수 없습니다: ERROR:  replication slot "geo_secondary_my_domain_com" does not exist

secondary 사이트에서 복제 프로세스를 다시 실행해 보세요.

메시지: 복제를 설정할 때 “Command exceeded allowed execution time”가 발생하나요?

이 문제는 secondary 사이트에서 복제 프로세스를 시작할 때 발생할 수 있으며, 초기 데이터 세트가 기본 타임아웃(30분) 내에 복제하기에는 너무 크다는 것을 나타냅니다.

gitlab-ctl replicate-geo-database를 다시 실행하되, --backup-timeout에 더 큰 값을 포함하세요:

sudo gitlab-ctl \
   replicate-geo-database \
   --host=<primary_node_hostname> \
   --slot-name=<secondary_slot_name> \
   --backup-timeout=21600

이렇게 하면 초기 복제에 최대 6시간이 주어져 기본 30분보다 긴 시간이 됩니다. 설치에 맞게 조정하세요.

메시지: “PANIC: could not write to file pg_xlog/xlogtemp.123: No space left on device”

primary 데이터베이스에 사용하지 않는 복제 슬롯이 있는지 확인하세요. 이것은 pg_xlog에 대량의 로그 데이터가 쌓이는 원인이 될 수 있습니다.

비활성 슬롯 제거하기pg_xlog에서 사용하는 공간을 줄일 수 있습니다.

메시지: “ERROR: canceling statement due to conflict with recovery”

이 오류 메시지는 일반적인 사용 중에는 드물게 발생하며 시스템은 복구할 수 있을 만큼 충분히 탄력적입니다.

하지만 특정 조건에서는, secondary에서 일부 데이터베이스 쿼리가 지나치게 오랜 시간이 걸릴 수 있으며, 이로 인해 이 오류 메시지가 발생하는 빈도가 증가할 수 있습니다. 이는 모든 복제 과정에서 취소되어 쿼리가 완료되지 않는 상황으로 이어질 수 있습니다.

이러한 오랜 실행 쿼리는 앞으로 제거될 계획입니다, 그러나 해결책으로, hot_standby_feedback을 활성화하는 것을 권장합니다.

이것은 primary 사이트에서 최근에 삭제된 행을 제거하는 VACUUM을 방지하므로 부풀림(bloat)의 가능성을 높입니다. 그러나 GitLab.com의 프로덕션에서 성공적으로 사용되었습니다.

hot_standby_feedback를 활성화하려면, secondary 사이트의 /etc/gitlab/gitlab.rb에 다음을 추가하세요:

postgresql['hot_standby_feedback'] = 'on'

그런 다음 GitLab을 재구성하세요:

sudo gitlab-ctl reconfigure

이 문제를 해결하는 데 도움이 되도록 문제에 댓글을 달아주십시오.

메시지: server certificate for "PostgreSQL" does not match host name

이 오류가 발생하면:

FATAL:  기본 서버에 연결할 수 없습니다: server certificate for "PostgreSQL" does not match host name

이는 Linux 패키지가 자동으로 생성하는 PostgreSQL 인증서에 Common Name PostgreSQL이 포함되어 있지만, 복제가 다른 호스트에 연결되고 GitLab이 기본적으로 verify-full SSL 모드를 사용하려고 시도하기 때문에 발생합니다.

이 문제를 해결하려면 다음 중 하나를 선택하세요:

  • replicate-geo-database 명령에 --sslmode=verify-ca 인수를 사용하세요.
  • 이미 복제된 데이터베이스의 경우, /var/opt/gitlab/postgresql/data/gitlab-geo.conf에서 sslmode=verify-fullsslmode=verify-ca로 변경한 후 gitlab-ctl restart postgresql를 실행하세요.
  • PostgreSQL의 SSL 구성하기에서 사용자 인증서를 사용하여 데이터베이스에 연결하는 데 사용되는 호스트 이름을 CN 또는 SAN에 포함하세요.

메시지: LOG: invalid CIDR mask in address

이 메시지는 postgresql['md5_auth_cidr_addresses']에 잘못 포맷된 주소로 인해 발생합니다.

2020-03-20_23:59:57.60499 LOG:  invalid CIDR mask in address "***"
2020-03-20_23:59:57.60501 CONTEXT:  line 74 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

이 문제를 해결하려면 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses']에서 IP 주소를 업데이트하여 CIDR 형식을 준수하도록 합니다 (예: 10.0.0.1/32).

메시지: LOG: invalid IP mask "md5": Name or service not known

이 메시지는 postgresql['md5_auth_cidr_addresses']에 서브넷 마스크 없이 IP 주소를 추가했을 때 발생합니다.

2020-03-21_00:23:01.97353 LOG:  invalid IP mask "md5": Name or service not known
2020-03-21_00:23:01.97354 CONTEXT:  line 75 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

이 문제를 해결하려면 /etc/gitlab/gitlab.rbpostgresql['md5_auth_cidr_addresses']에 서브넷 마스크를 추가하여 CIDR 형식을 준수하도록 합니다 (예: 10.0.0.1/32).

메시지: Found data in the gitlabhq_production database

gitlab-ctl replicate-geo-database를 실행할 때 Found data in the gitlabhq_production database!라는 오류 메시지를 수신하는 경우, projects 테이블에서 데이터가 감지되었음을 의미합니다. 하나 이상의 프로젝트가 감지되면 사고로 데이터 손실을 방지하기 위해 작업이 중단됩니다. 이 메시지를 우회하려면 명령에 --force 옵션을 전달하세요.

메시지: FATAL: could not map anonymous shared memory: Cannot allocate memory

이 메시지가 표시되면 보조 사이트의 PostgreSQL에서 사용 가능한 메모리보다 높은 메모리를 요청하고 있음을 의미합니다. 이 문제를 추적하는 이슈가 있습니다.

리눅스 패키지 설치의 경우 ‘/var/log/gitlab/patroni/current’에 위치한 Patroni 로그에서의 예시 오류 메시지:

2023-11-21_23:55:18.63727 FATAL:  could not map anonymous shared memory: Cannot allocate memory
2023-11-21_23:55:18.63729 HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 17035526144 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

작업 해결 방법은 보조 사이트의 PostgreSQL 노드에서 기본 사이트의 PostgreSQL 노드의 메모리 요구 사항에 맞게 사용 가능한 메모리를 늘리는 것입니다.

비-PostgreSQL 복제 실패 수정

관리 > Geo > 사이트 또는 Sync status Rake 작업에서 복제 실패가 발생하면 다음 일반적인 단계를 통해 실패를 해결할 수 있습니다.

  1. Geo는 자동으로 실패를 재시도합니다. 실패가 새롭고 수가 적거나, 원인이 이미 해결되었다고 의심되는 경우, 실패가 사라지는지 확인하기 위해 기다릴 수 있습니다.

  2. 실패가 오랜 시간 동안 발생했다면, 이미 많은 재시도가 이루어졌으며, 자동 재시도 간격이 실패 유형에 따라 최대 4시간으로 증가했습니다. 원인이 이미 해결되었다고 의심되는 경우, 복제를 수동으로 재시도하거나 검증할 수 있습니다.

  3. 실패가 지속되면 다음 섹션을 사용하여 해결을 시도하세요.

수동으로 복제 또는 검증 다시 시도하기

Geo 데이터 유형은 하나 이상의 GitLab 기능에서 관련 정보를 저장하는 데 필요한 특정 데이터 클래스이며, Geo에 의해 보조 사이트로 복제됩니다.

다음의 Geo 데이터 유형이 존재합니다:

  • Blob 유형:
    • Ci::JobArtifact
    • Ci::PipelineArtifact
    • Ci::SecureFile
    • LfsObject
    • MergeRequestDiff
    • Packages::PackageFile
    • PagesDeployment
    • Terraform::StateVersion
    • Upload
    • DependencyProxy::Manifest
    • DependencyProxy::Blob
  • Git 리포지토리 유형:
    • DesignManagement::Repository
    • ProjectRepository
    • ProjectWikiRepository
    • SnippetRepository
    • GroupWikiRepository
  • 기타 유형:
    • ContainerRepository

주요 클래스 종류는 Registry, Model, 그리고 Replicator입니다. 이들 클래스 중 하나의 인스턴스가 있으면 나머지를 얻을 수 있습니다. Registry와 Model은 주로 PostgreSQL DB 상태를 관리합니다. Replicator는 복제/검증하는 방법을 알고 있거나 이를 수행하는 서비스를 호출할 수 있습니다:

model_record = Packages::PackageFile.last
model_record.replicator.registry.replicator.model_record # 이러한 메소드들이 존재함을 보여줍니다

이 모든 정보를 바탕으로, 다음을 수행할 수 있습니다:

개별 구성 요소 수동 다시 동기화 및 재검증

개별 항목을 강제로 다시 동기화하고 재검증할 수 있습니다

모든 구성 요소 유형은 자체 서비스 프레임워크를 사용하여 UI를 통해 관리됩니다.

보조 사이트에서 관리 > Geo > 복제를 방문하세요.

그러나 이 방법이 작동하지 않으면 Rails 콘솔을 사용하여 동일한 작업을 수행할 수 있습니다. 다음 섹션에서는 Rails 콘솔에서 내부 애플리케이션 명령을 사용하는 방법을 설명합니다. 이를 통해 개별 레코드를 동기식 또는 비동기식으로 복제 또는 검증할 수 있습니다.

경고: 데이터를 변경하는 명령은 올바른 조건에서에 실행되지 않거나 잘못 실행될 경우 손상을 일으킬 수 있습니다. 항상 먼저 테스트 환경에서 명령을 실행하고 복원할 준비가 된 백업 인스턴스를 확보하세요.

Rails 콘솔 세션 시작하기를 통해 다음의 기본 문제 해결 단계를 실행할 수 있습니다:

  • Blob 유형의 경우 (Packages::PackageFile 구성 요소를 예로)

    • 동기화에 실패한 레지스트리 레코드 찾기:

      Geo::PackageFileRegistry.failed
      

      이 경우 레지스트리 레코드는 Geo 추적 데이터베이스에 있는 레지스트리 테이블을 나타냅니다. 각 레코드 또는 행은 LFS 파일 또는 프로젝트 Git 리포지토리와 같은 GitLab 데이터베이스의 단일 복제 가능 항목을 추적합니다. 다음은 위와 같이 쿼리할 수 있는 Geo 레지스트리 테이블에 해당하는 다른 Rails 모델입니다:

      CiSecureFileRegistry
      ContainerRepositoryRegistry
      DependencyProxyBlobRegistry
      DependencyProxyManifestRegistry
      JobArtifactRegistry
      LfsObjectRegistry
      MergeRequestDiffRegistry
      PackageFileRegistry
      PagesDeploymentRegistry
      PipelineArtifactRegistry
      ProjectWikiRepositoryRegistry
      SnippetRepositoryRegistry
      TerraformStateVersionRegistry
      UploadRegistry
      
    • 기본 사이트에서 누락된 레지스트리 레코드 찾기:

      Geo::PackageFileRegistry.where(last_sync_failure: 'The file is missing on the Geo primary site')
      
    • ID를 주고 패키지 파일을 동기식으로 다시 동기화하기:

      model_record = Packages::PackageFile.find(id)
      model_record.replicator.sync
      
    • 레지스트리 ID를 주고 패키지 파일을 동기식으로 다시 동기화하기:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.sync
      
    • 레지스트리 ID를 주고 패키지 파일을 비동기식으로 다시 동기화하기. GitLab 16.2 이후, 구성 요소는 다음과 같이 비동기식으로 복제될 수 있습니다:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.enqueue_sync
      
    • 레지스트리 ID를 주고 패키지 파일을 비동기식으로 재검증하기. GitLab 16.2 이후, 구성 요소는 다음과 같이 비동기식으로 재검증될 수 있습니다:

      registry = Geo::PackageFileRegistry.find(registry_id)
      registry.replicator.verify_async
      
  • 리포지토리 유형의 경우 (SnippetRepository 구성 요소를 예로)

    • ID를 주고 스니펫 리포지토리를 동기식으로 다시 동기화하기:

      model_record = Geo::SnippetRepositoryRegistry.find(id)
      model_record.replicator.sync
      
    • 레지스트리 ID를 주고 스니펫 리포지토리를 동기식으로 다시 동기화하기:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.sync
      
    • 레지스트리 ID를 주고 스니펫 리포지토리를 비동기식으로 다시 동기화하기. GitLab 16.2 이후, 구성 요소는 다음과 같이 비동기식으로 복제될 수 있습니다:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.enqueue_sync
      
    • 레지스트리 ID를 주고 스니펫 리포지토리를 비동기식으로 재검증하기. GitLab 16.2 이후, 구성 요소는 다음과 같이 비동기식으로 재검증될 수 있습니다:

      registry = Geo::SnippetRepositoryRegistry.find(registry_id)
      registry.replicator.verify_async
      

여러 구성 요소 다시 동기화 및 재확인

note
이 기능을 Admin 영역 UI에 구현하는 문제가 있습니다.
caution
데이터를 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건에서 실행되지 않을 경우 손상을 일으킬 수 있습니다. 항상 테스트 환경에서 먼저 명령을 실행하고 복원할 준비가 된 백업 인스턴스를 보유하십시오.

다음 섹션에서는 Rails 콘솔에서 내부 애플리케이션 명령을 사용하여 대량 복제 또는 확인을 수행하는 방법을 설명합니다.

모든 구성 요소 (또는 확인을 지원하는 모든 SSF 데이터 유형) 재확인

GitLab 16.4 및 이전 버전의 경우:

  1. 기본 Geo 사이트의 GitLab Rails 노드에 SSH로 로그인합니다.

  2. Rails 콘솔을 엽니다.

  3. 모든 업로드를 pending verification으로 표시합니다:

    Upload.verification_state_table_class.each_batch do |relation|
      relation.update_all(verification_state: 0)
    end
    
  4. 이로 인해 기본 노드는 모든 업로드에 대해 체크섬을 시작합니다.

  5. 기본 노드가 레코드의 체크섬을 성공적으로 계산하면 모든 보조 노드도 체크섬을 재계산하고 값을 비교합니다.

다른 SSF 데이터 유형에 대해 위 명령의 Upload를 원하는 모델 클래스로 교체하십시오.

보조에서 blob 파일 수동 확인

이 작업은 보조에서 모든 패키지 파일을 반복하여 데이터베이스에 저장된 verification_checksum(기본 노드에서 온 것)을 확인한 후 이 값을 보조에서 계산하여 일치하는지 확인합니다. 이 작업은 UI에서 아무것도 변경하지 않습니다.

# 보조에서 실행
status = {}

Packages::PackageFile.find_each do |package_file|
  primary_checksum = package_file.verification_checksum
  secondary_checksum = Packages::PackageFile.sha256_hexdigest(package_file.file.path)
  verification_status = (primary_checksum == secondary_checksum)

  status[verification_status.to_s] ||= []
  status[verification_status.to_s] << package_file.id
end

# 각 값의 개수를 센다
status.keys.each {|key| puts "#{key} count: #{status[key].count}"}

# 전체 출력을 봅니다
status

기본 Geo 사이트에서 업로드의 확인 실패

기본 Geo 사이트에서 일부 업로드의 확인이 verification_checksum = nilverification_failure = Error during verification: undefined method 'underscore' for NilClass:Class와 함께 실패하는 경우, 이는 고아 업로드 때문일 수 있습니다. 업로드를 소유한 부모 레코드(업로드의 모델)가 삭제되었지만 업로드 레코드는 여전히 존재하는 경우입니다. 이러한 확인 실패는 잘못된 것입니다.

이러한 오류는 기본 Geo 사이트의 geo.log 파일에서 확인할 수 있습니다.

모델 레코드가 누락되었는지 확인하려면 기본 Geo 사이트에서 Rake 작업을 실행할 수 있습니다:

sudo gitlab-rake gitlab:uploads:check

기본 Geo 사이트에서 이러한 실패를 제거하기 위해 다음 스크립트를 Rails 콘솔에서 실행하여 이러한 업로드 레코드를 삭제할 수 있습니다:

# 확인 오류가 있는 업로드를 찾습니다
# 또는 영향을 받는 ID로 수정하십시오
uploads = Geo::UploadState.where(
  verification_checksum: nil,
  verification_state: 3,
  verification_failure: "Error during verification: undefined method  `underscore' for NilClass:Class"
).pluck(:upload_id)

uploads_deleted = 0
begin
    uploads.each do |upload|
    u = Upload.find upload
    rescue => e
        puts "업로드 #{u.id} 확인 실패: #{e.message}"
      else
        uploads_deleted=uploads_deleted + 1
        p u                            ### 삭제 전에 확인 허용
        # p u.destroy!                 ### 실제 삭제하려면 주석 제거
  end
end
p "#{uploads_deleted} 원격 객체가 삭제되었습니다."

오류: Error syncing repository: 13:fatal: could not read Username

last_sync_failure 오류

Error syncing repository: 13:fatal: could not read Username for 'https://gitlab.example.com': terminal prompts disabled

는 Geo 클론 또는 가져오기 요청 중 JWT 인증이 실패하고 있음을 나타냅니다.

더 많은 맥락은 Geo (개발) > 인증을 참조하세요.

먼저, 시스템 클록이 동기화되었는지 확인하세요. 헬스 체크 Rake 작업을 실행하거나, 보조 사이트의 모든 Sidekiq 노드와 기본 사이트의 모든 Puma 노드에서 date가 동일한지 수동으로 확인하세요.

시스템 클록이 동기화되어 있다면, Git fetch가 두 개의 별도 HTTP 요청 간에 계산을 수행하는 동안 JWT 토큰이 만료되고 있을 수 있습니다. 문제 464101을 참조하세요. 이 문제는 GitLab 17.1.0, 17.0.5 및 16.11.7에서 수정될 때까지 모든 GitLab 버전에서 존재했습니다.

이 문제를 경험하고 있는지 확인하려면:

  1. Rails 콘솔에서 코드를 몽키 패치하여 토큰의 유효 기간을 1분에서 10분으로 늘리세요. 보조 사이트의 Rails 콘솔에서 다음을 실행하세요:

    module Gitlab; module Geo; class BaseRequest
      private
      def geo_auth_token(message)
        signed_data = Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes).sign_and_encode_data(message)
    
        "#{GITLAB_GEO_AUTH_TOKEN_TYPE} #{signed_data}"
      end
    end;end;end
    
  2. 같은 Rails 콘솔에서 영향을 받는 프로젝트를 다시 동기화하세요:

    Project.find_by_full_path('mygroup/mysubgroup/myproject').replicator.resync
    
  3. 동기화 상태를 확인하세요:

    Project.find_by_full_path('mygroup/mysubgroup/myproject').replicator.registry
    
  4. 만약 last_sync_failure가 더 이상 fatal: could not read Username 오류를 포함하지 않는다면, 이 이슈에 영향을 받고 있는 것입니다. 상태는 이제 2가 되어 “동기화됨”을 의미합니다. 그렇다면, 수정 사항이 포함된 GitLab 버전으로 업그레이드해야 합니다. 또한, 이 문제의 심각성을 줄였을 문제 466681에 투표하거나 댓글을 달고 싶을 수 있습니다.

이 문제의 해결 방법으로 다음을 수행해야 합니다. 보조 사이트의 모든 Sidekiq 노드를 핫 패치하여 JWT 만료 시간을 늘리세요:

  1. /opt/gitlab/embedded/service/gitlab-rails/ee/lib/gitlab/geo/signed_data.rb를 편집하세요.

  2. Gitlab::Geo::SignedData.new(geo_node: requesting_node)를 찾아 다음과 같이 , validity_period: 10.minutes를 추가하세요:

    - Gitlab::Geo::SignedData.new(geo_node: requesting_node)
    + Gitlab::Geo::SignedData.new(geo_node: requesting_node, validity_period: 10.minutes)
    
  3. Sidekiq를 재시작하세요:

    sudo gitlab-ctl restart sidekiq
    
  4. 수정 사항이 포함된 버전으로 업그레이드하지 않는 한, GitLab 업그레이드 후마다 이 해결 방법을 반복해야 합니다.

오류: fetch remote: signal: terminated: context deadline exceeded가 정확히 3시간에 발생

Git fetch가 Git 저장소를 동기화하는 중 정확히 3시간에 실패하는 경우:

  1. /etc/gitlab/gitlab.rb를 편집하여 Git 타임아웃을 기본값인 10800초에서 증가시킵니다:

    # Git 타임아웃(초 단위)
    gitlab_rails['gitlab_shell_git_timeout'] = 21600
    
  2. GitLab을 재구성합니다:

    sudo gitlab-ctl reconfigure
    

오류 Failed to open TCP connection to localhost:5000가 보조에서 레지스트리 복제를 구성할 때 발생

보조 사이트에서 컨테이너 레지스트리 복제를 구성할 때 다음과 같은 오류가 발생할 수 있습니다:

Failed to open TCP connection to localhost:5000 (Connection refused - connect(2) for \"localhost\" port 5000)"

이는 보조 사이트에서 컨테이너 레지스트리가 활성화되지 않은 경우 발생합니다. 이를 해결하려면 컨테이너 레지스트리가 보조 사이트에서 활성화되어 있는지 확인하세요. 또한 Let’s Encrypt 통합이 비활성화되어 있는 경우 컨테이너 레지스트리도 비활성화되며, 이를 수동으로 구성해야 합니다.

데이터베이스 복제 지연 원인 조사

sudo gitlab-rake geo:status의 출력에서 Database replication lag가 시간이 지남에 따라 상당히 높게 유지되는 경우 데이터베이스 복제의 기본 노드를 확인하여 데이터베이스 복제 프로세스의 다양한 부분에 대한 지연 상태를 확인할 수 있습니다. 이러한 값은 write_lag, flush_lag, 및 replay_lag로 알려져 있습니다. 자세한 정보는 공식 PostgreSQL 문서를 참조하세요.

주요 Geo 노드의 데이터베이스에서 관련 출력을 제공하기 위해 다음 명령을 실행하십시오:

gitlab-psql -xc 'SELECT write_lag,flush_lag,replay_lag FROM pg_stat_replication;'

-[ RECORD 1 ]---------------
write_lag  | 00:00:00.072392
flush_lag  | 00:00:00.108168
replay_lag | 00:00:00.108283

이 값 중 하나 이상이 상당히 높으면 이는 문제를 나타낼 수 있으며 추가 조사가 필요합니다. 원인을 결정할 때 다음 사항을 고려하세요:

  • write_lag는 WAL 바이트가 주 노드에서 전송되고 보조 노드로 수신되었지만 아직 플러시되거나 적용되지 않은 시간을 나타냅니다.
  • 높은 write_lag 값은 주 노드와 보조 노드 간의 네트워크 성능 저하 또는 불충분한 네트워크 속도를 나타낼 수 있습니다.
  • 높은 flush_lag 값은 보조 노드의 저장 장치에서 I/O 성능 저하 또는 최적화되지 않은 상태를 나타낼 수 있습니다.
  • 높은 replay_lag 값은 PostgreSQL에서 실행 시간이 긴 트랜잭션이나 CPU와 같은 필요한 리소스의 포화 상태를 나타낼 수 있습니다.
  • write_lagflush_lag 간의 시간 차이는 WAL 바이트가 기본 저장 시스템에 전송되었지만 플러시되었다고 보고되지 않았음을 나타냅니다. 이 데이터는 영구 저장소에 완전히 기록되지 않았으며, 아마도 어떤 형태의 휘발성 쓰기 캐시에 보관되었을 가능성이 높습니다.
  • flush_lagreplay_lag 간의 차이는 저장소에 성공적으로 지속된 WAL 바이트가 데이터베이스 시스템에 의해 재생되지 못했음을 나타냅니다.

Geo secondary 사이트 복제 재설정

secondary 사이트가 손상된 상태에 있고 복제 상태를 재설정하여 처음부터 시작하려면 도움이 될 수 있는 몇 가지 단계가 있습니다:

  1. Sidekiq 및 Geo 로그 커서를 중지합니다.

    Sidekiq를 정상적으로 중지하는 것이 가능하지만, 새로운 작업을 받지 않도록 중지하고 현재 작업이 처리 완료될 때까지 기다리게 할 수 있습니다.

    첫 번째 단계에서는 SIGTSTP 킬 신호를 보내고 모든 작업이 완료되었을 때 SIGTERM을 보내야 합니다. 그렇지 않다면 gitlab-ctl stop 명령어를 사용하세요.

    gitlab-ctl status sidekiq
    # 실행: sidekiq: (pid 10180) <- 이 PID를 사용합니다
    kill -TSTP 10180 # 올바른 PID로 변경
    
    gitlab-ctl stop sidekiq
    gitlab-ctl stop geo-logcursor
    

    Sidekiq 작업 처리가 완료되었는지 확인하려면 Sidekiq 로그를 확인할 수 있습니다:

    gitlab-ctl tail sidekiq
    
  2. Gitaly/Gitaly 클러스터 데이터를 지웁니다.

    Gitaly
    mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
    sudo gitlab-ctl reconfigure
    
    Gitaly Cluster
    1. 선택사항. Praefect 내부 로드 밸런서를 비활성화합니다.

    2. 각 Praefect 서버에서 Praefect를 중지합니다:

      sudo gitlab-ctl stop praefect
      
    3. Praefect 데이터베이스를 재설정합니다:

      sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "DROP DATABASE praefect_production WITH (FORCE);"
      sudo /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h localhost -c "CREATE DATABASE praefect_production WITH OWNER=praefect ENCODING=UTF8;"
      
    4. 각 Gitaly 노드에서 저장소 데이터를 이름 변경/삭제합니다:

      sudo mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
      sudo gitlab-ctl reconfigure
      
    5. Praefect 배포 노드에서 데이터베이스를 설정하기 위해 재구성합니다:

      sudo gitlab-ctl reconfigure
      
    6. 각 Praefect 서버에서 Praefect를 시작합니다:

      sudo gitlab-ctl start praefect
      
    7. 선택사항. 비활성화했던 경우 Praefect 내부 로드 밸런서를 재활성화합니다.

    주의: 더 이상 필요하지 않음을 확인한 후, 디스크 공간을 절약하기 위해 /var/opt/gitlab/git-data/repositories.old를 삭제할 수 있습니다.

  3. 선택사항. 기타 데이터 폴더의 이름을 변경하고 새 폴더를 만듭니다.

    경고: secondary 사이트에 primary 사이트에서 제거된 파일이 여전히 존재할 수 있으나, 이러한 제거가 반영되지 않을 수 있습니다. 이 단계를 건너뛰면 이러한 파일은 Geo secondary 사이트에서 제거되지 않습니다.

    업로드된 콘텐츠(파일 첨부 파일, 아바타, LFS 객체 등)는 다음 경로 중 하나의 하위 폴더에 저장됩니다:

    • /var/opt/gitlab/gitlab-rails/shared
    • /var/opt/gitlab/gitlab-rails/uploads

    모두 이름을 변경하려면:

    gitlab-ctl stop
    
    mv /var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared.old
    mkdir -p /var/opt/gitlab/gitlab-rails/shared
    
    mv /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads.old
    mkdir -p /var/opt/gitlab/gitlab-rails/uploads
    
    gitlab-ctl start postgresql
    gitlab-ctl start geo-postgresql
    

    폴더를 다시 생성하고 권한 및 소유권이 올바른지 확인하려면 재구성합니다:

    gitlab-ctl reconfigure
    
  4. 추적 데이터베이스를 재설정합니다.

    경고: 선택 사항 3을 건너뛰었다면 geo-postgresqlpostgresql 서비스가 모두 실행되고 있는지 확인하세요.

    gitlab-rake db:drop:geo DISABLE_DATABASE_ENVIRONMENT_CHECK=1   # secondary 앱 노드에서
    gitlab-ctl reconfigure     # 추적 데이터베이스 노드에서
    gitlab-rake db:migrate:geo # secondary 앱 노드에서
    
  5. 이전에 중지한 서비스를 재시작합니다.

    gitlab-ctl start