CI 미러링 테이블
문제 설명
main
과 ci
두 개의 데이터베이스로 GitLab이 사용하던 단일 데이터베이스를 분리하는 목표를 가진 분해 작업의 일환으로 main
과 ci
테이블 간의 조인을 모두 제거하는 일이 있었습니다. 이는 PostgreSQL이 서로 다른 데이터베이스에 속하는 테이블 간의 조인을 지원하지 않기 때문입니다. 그러나 main
데이터베이스의 일부 핵심 애플리케이션 모델은 CI 쪽에서 매우 자주 쿼리됩니다. 예를 들면:
-
namespaces
테이블에 있는Namespace
-
projects
테이블에 있는Project
이러한 테이블에서 join
을 할 수 없는 것은 큰 도전입니다. 팀은 main
데이터베이스의 해당 테이블을 ci
데이터베이스로 논리적으로 복제하기로 선택했으며, 새로운 테이블은 다음과 같습니다:
-
namespaces
테이블의 미러로ci_namespace_mirrors
-
projects
테이블의 미러로ci_project_mirrors
이 논리적 복제는 두 가지를 의미합니다:
-
main
데이터베이스의 테이블을namespaces
및projects
테이블에 조인하여 쿼리할 수 있습니다. -
ci
데이터베이스의 테이블을ci_namespace_mirrors
및ci_project_mirrors
테이블과 조인할 수 있습니다.
이 복제는 각 모델에서 필요한 몇 가지 속성에만 제한되어 있습니다:
-
Namespace
에서는traversal_ids
를 복제합니다. -
Project
에서는 프로젝트가 속한 그룹을 나타내는namespace_id
만을 복제합니다.
소스 테이블과 대상 테이블 사이의 CI 미러링 테이블 동기화 유지
소스 테이블과 대상 테이블을 동기화하려면 두 가지 유형의 이벤트에 유의해야 합니다:
- 새로운 네임스페이스 또는 프로젝트 생성
- 네임스페이스 또는 프로젝트 업데이트
- 네임스페이스/프로젝트 삭제
생성 및 업데이트
새로 생성되거나 업데이트된 네임스페이스나 프로젝트의 데이터를 동기화하는 방법은 다음과 같습니다:
-
main
데이터베이스에서:namespaces
또는projects
테이블에 대한 어떠한INSERT
또는UPDATE
는namespaces_sync_events
및projects_sync_events
테이블에 항목을 추가합니다. 이러한 테이블은main
데이터베이스에도 존재합니다. 이러한 항목들은 각각의 테이블에 트리거에 의해 추가됩니다. -
모델 단계에서:
Namespace
또는Project
중 하나에서 커밋이 일어나면, 해당하는 Sidekiq 작업Namespaces::ProcessSyncEventsWorker
또는Projects::ProcessSyncEventsWorker
가 예약됩니다. - 이러한 워커는:
-
main
데이터베이스의(namespaces/project)_sync_events
테이블에서 항목을 읽어 어떤 네임스페이스나 프로젝트를 동기화할지 확인합니다. - 변경된 레코드의 데이터를 대상 테이블인
ci_namespace_mirrors
,ci_project_mirrors
로 복사합니다.
-
삭제
namespaces
또는 projects
중 하나가 삭제되면, 미러링된 CI 테이블의 대상 레코드는 loose foreign keys (LFK) 메커니즘을 사용하여 삭제됩니다.
config/gitlab_loose_foreign_keys.yml
에 이러한 항목들을 두어, LFK 메커니즘이 기대한대로 작동했습니다. 이는 main
데이터베이스에서 삭제된 namespaces
또는 projects
에 매핑된 CI 미러링된 테이블의 모든 레코드를 삭제했습니다.
ci_namespace_mirrors:
- 테이블: namespaces
열: namespace_id
삭제 시: 비동기적으로 삭제
ci_project_mirrors:
- 테이블: projects
열: project_id
삭제 시: 비동기적으로 삭제
일관성 확인
동기화 메커니즘이 예상대로 작동하는지 확인하기 위해, 몇 분마다 크론 작업에 의해 트리거된 두 개의 추가적인 워커 작업을 배포합니다:
Database::CiNamespaceMirrorsConsistencyCheckWorker
Database::CiProjectMirrorsConsistencyCheckWorker
이러한 작업들은:
-
main
데이터베이스의 소스 테이블들을 커서를 사용하여 스캔합니다. -
ci
데이터베이스의 대상 테이블과namespaces
및projects
를 비교합니다. - 동기화되지 않은 항목들을 Kibana와 Prometheus에 보고합니다.
- 어떠한 불일치도 정정합니다.