느슨한 외래 키(Loose Foreign Keys)
GitLab에서 다중 데이터베이스 환경의 데이터 일관성을 비동기 방식으로 유지하기 위한 느슨한 외래 키(Loose Foreign Keys) 기능의 구현 방법과 설정, 아키텍처를 설명합니다.
문제 정의 # 관계형 데이터베이스(PostgreSQL 포함)에서 외래 키는 두 데이터베이스 테이블을 연결하고 테이블 간 데이터 일관성을 보장하는 방법을 제공합니다. GitLab에서 외래 키 는 데이터베이스 설계 프로세스의 핵심 요소입니다. 대부분의 데이터베이스 테이블에는 외래 키가 있습니다. 진행 중인 데이터베이스 분해 작업 으로 인해, 연결된 레코드가 두 개의 서로 다른 데이터베이스 서버에 존재할 수 있습니다. 두 데이터베이스 간의 데이터 일관성 보장은 표준 PostgreSQL 외래 키로는 불가능합니다. PostgreSQL은 여러 데이터베이스 서버에 걸친 외래 키를 지원하지 않습니다. 예시: 데이터베이스 "Main": projects 테이블 데이터베이스 "CI": ci_pipelines 테이블 프로젝트는 여러 파이프라인을 가질 수 있습니다. 프로젝트가 삭제될 때, ( project_id 칼럼을 통해) 연관된 ci_pipeline 레코드도 함께 삭제되어야 합니다. 다중 데이터베이스 설정에서는 외래 키로 이를 달성할 수 없습니다. 비동기 방식 # 이 문제에 대한 선호하는 접근 방식은 최종적 일관성(eventual consistency)입니다. 느슨한 외래 키 기능을 사용하면 애플리케이션 성능에 부정적인 영향을 미치지 않으면서 지연된 연관 관계 정리를 설정할 수 있습니다. 최종적 일관성의 구현 방식 # 앞의 예시에서, projects 테이블의 레코드는 여러 ci_pipeline 레코드를 가질 수 있습니다. 정리 프로세스를 실제 부모 레코드 삭제와 분리하기 위해 다음과 같이 할 수 있습니다: projects 테이블에 DELETE 트리거를 생성합니다. 별도 테이블( deleted_records )에 삭제 내역을 기록합니다. job이 1~2분마다 deleted_records 테이블을 확인합니다. 테이블의 각 레코드에 대해, project_id 칼럼을 사용하여 연관된 ci_pipelines 레코드를 삭제합니다. 이 절차가 작동하려면, 비동기적으로 정리할 테이블을 등록해야 합니다. scripts/decomposition/generate-loose-foreign-key # 저희는 분해 작업의 일환으로 외래 키를 느슨한 외래 키로 마이그레이션하는 것을 지원하기 위한 자동화 도구를 구축했습니다. 이 도구는 기존 키를 표시하고 선택된 외래 키를 자동으로 느슨한 외래 키로 변환할 수 있습니다. 이를 통해 외래 키와 느슨한 외래 키 정의 간의 일관성을 보장하고, 올바르게 테스트되었는지 확인합니다. 외래 키를 느슨한 외래 키로 교체할 때 자동화 스크립트를 사용하는 것을 강력히 권장합니다. 이 도구는 외래 키 교체의 모든 측면이 처리되도록 합니다. 여기에는 다음이 포함됩니다: 외래 키 제거를 위한 마이그레이션 생성. 새 마이그레이션으로 db/structure.sql 업데이트. 새 느슨한 외래 키를 추가하기 위해 config/gitlab_loose_foreign_keys.yml 업데이트. 느슨한 외래 키가 올바르게 지원되는지 확인하기 위해 모델의 spec 생성 또는