CI 미러링된 테이블
문제 설명
분해 작업의 일환으로, GitLab이 사용 중인 단일 데이터베이스를 두 개의 데이터베이스, main
과 ci
로 분할하는 것이 목표였습니다. 이 과정에서 main
과 ci
테이블 간의 모든 조인을 제거하는 것이 큰 과제가 되었습니다. PostgreSQL은 서로 다른 데이터베이스에 속하는 테이블 간의 조인을 지원하지 않기 때문입니다. 그러나 main
데이터베이스의 일부 핵심 애플리케이션 모델은 CI 측에서 매우 자주 쿼리됩니다.
예를 들어:
-
namespaces
테이블의Namespace
-
projects
테이블의Project
이러한 테이블에서 조인을 수행할 수 없는 것은 큰 도전입니다. 팀은 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 메커니즘이 예상대로 작동했습니다. CI 미러링된 테이블에서 삭제된 main
데이터베이스의 namespaces
또는 projects
에 매핑된 레코드를 삭제했습니다.
ci_namespace_mirrors:
- table: namespaces
column: namespace_id
on_delete: async_delete
ci_project_mirrors:
- table: projects
column: project_id
on_delete: async_delete
일관성 검사
두 동기화 매커니즘이 예상대로 작동하는지 확인하기 위해 몇 분마다 크론 작업에 의해 트리거되는 두 개의 추가 작업자 작업을 배포합니다.
Database::CiNamespaceMirrorsConsistencyCheckWorker
Database::CiProjectMirrorsConsistencyCheckWorker
이러한 작업은 다음과 같은 작업을 수행합니다.
- 메인 데이터베이스의 소스 테이블을 커서를 사용하여 스캔합니다.
-
ci
데이터베이스의 대상 테이블과namespaces
및projects
의 항목을 비교합니다. - 동기화되지 않은 항목을 Kibana 및 Prometheus에 보고합니다.
- 어떠한 불일치 사항도 수정합니다.