This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
implemented @abrandl @glopezfernandez @fabian @craig-gomes devops data stores 2021-02-08

데이터베이스 테스팅

알림: 이 블루프린트는 일부분이 구현되었습니다. 여전히 도구를 개선할 계획이 있습니다. 아래 내용은 개발 워크플로에 데이터베이스 테스팅을 통합하기 전에 작성된 블루프린트의 이전 버전입니다.

공통 특징인 되돌린 마이그레이션의 일반적인 주제를 식별했으며, 개발자 환경에서 성공적으로 테스트한 것에도 불구하고 프로덕션 및 스테이징에서 실패한 마이그레이션을 발견했습니다. 또한 스테이징에서 성공적으로 테스트한 것에도 불구하고 프로덕션에서 프로덕션적 문제가 발생했습니다. 이러한 실패는 상당히 비용이 많이 듭니다. 가용성에 상당한 영향을 미치며, 배포를 차단하고 사고 전파를 유발할 수 있습니다. 이러한 사고 전파는 트리지되어 복귀되거나 전진 수정되어야 합니다. 일반적으로 이는 원저자의 참여 없이 시간대 문제 및/또는 사고 전파의 중요성 때문에 일어날 수 있습니다. 저희의 증가된 배포 속도와 엄격해진 가동 시간 요구로 인해 데이터베이스 테스팅을 개선해야 할 필요성이 큽니다, 특히 개발 과정 초기에(shift left).

개발자 관점에서는 프로덕션 환경으로 마이그레이션을 검증하는 것은 어렵거나 불가능할 수 있습니다.

우리의 주요 목표는 **개발자에게 즉각적인 피드백을 제공하여 신규 마이그레이션 및 다른 데이터베이스 관련 변경 사항을 프로덕션 데이터베이스의 완전한 사본에서 테스트한 후에 제공하는 것이며, 이를 효율적으로(특히 인프라 비용 측면에서) 및 보안성 높게 수행하는 것입니다.

현재

개발자들은 어떠한 환경으로 배포하기 전에 데이터베이스 마이그레이션을 테스트하는 것을 요구받지만, GitLab.com과 같은 대규모 환경에서 테스트하는 능력이 부족합니다. 개발자 데이터베이스 마이그레이션 스타일 가이드는 마이그레이션에 대한 지침을 제공하며, 우리는 코드 리뷰에서 마이그레이션을 검증하고 CI 및 스테이징에서 테스트에 집중합니다.

코드 리뷰 단계에는 데이터베이스 리뷰어와 유지보수자가 매뉴얼으로 커밋된 마이그레이션을 확인합니다. 이는 일반적으로 GitLab.com에서의 문제가 있는 패턴을 경험으로 알아내고 발견해야 합니다. 마이그레이션을 Merge하기 전에 테스트할 수 있는 대규모 환경이 없습니다.

CI에서의 테스트는 매우 작은 데이터베이스에서 수행됩니다. 주로 전/후방 마이그레이션 일관성을 확인하고, RuboCop 규칙을 평가하여 잘 알려진 문제 행동(정적 코드 확인)을 감지하고 올바른 파일 추가 등의 몇 가지 기술적 검사가 있습니다. 다시 말해, 일반적으로 코드나 다른 간단한 오류를 찾지만 데이터 관련 오류를 드러내지 못할 뿐(일반적으로 유닛 테스트에서도 미처라지지 않습니다).

Merge한 후에, 마이그레이션은 스테이징 환경에 배포됩니다. 2021년 1월 기준으로 그 크기는 프로덕션 데이터베이스 크기의 5% 이하이며, 최근 데이터 분포가 프로덕션 사이트와 유사하지 않습니다. 종종, 스테이징에서 성공한 마이그레이션이 프로덕션에서 쿼리 타임아웃 또는 다른 예상치 못한 문제로 인해 실패합니다. 스테이징에서 문제를 발견했더라도 조정하는 데 비용이 많이 들며, 이상적으로는 개발 주기 초기에 가능한 빨리 이러한 문제를 발견하고 싶습니다.

오늘날, 우리는 얇게 복제된 프로덕션 데이터베이스에서 작업하는 데 경험을 쌓았으며, 이미 이를 통해 개발자에게 프로덕션 쿼리 계획, 자동화된 쿼리 피드백 및 최적화 제안을 제공하고 있습니다. 이는 Database LabJoe를 중심으로 하며, 이는 슬랙(ChatOps를 사용)과 postgres.ai에서 이용할 수 있습니다.

비전

개발자로서:

  1. GitLab 코드 변경에 기반한 데이터 마이그레이션 및 무거운 데이터베이스 쿼리 변경을 수행합니다.
  2. 코드를 푸시하고, Merge Request을 만들고, 설명에 쿼리 예제를 제공합니다.
  3. 파이프라인이 데이터 마이그레이션을 실행하고 대규모 환경(비슷한 GitLab.com의 사본)에서 쿼리를 조사합니다.
  4. 파이프라인이 완료되면, Merge Request은 마이그레이션 및 제공한 쿼리에 대한 자세한 피드백 및 정보를 받습니다. 이것은 프로덕션과 아주 비슷한 상태의 프로덕션 데이터베이스의 완전한 복제본에 기반합니다(분 단위).

데이터베이스 마이그레이션에 대한 정보 수집은 다음을 포함합니다:

  • 전반적인 실행 시간.
  • 마이그레이션에서 실행되는 쿼리에 대한 자세한 통계(쿼리 정규화 및 플롯으로 표시된 빈도 및 실행 시간).
  • 마이그레이션 중에 보유된 위험한 락(프로덕션에서 차단 상황을 유발할 수 있는 것).

데이터베이스 쿼리에 대해서는 자동으로 다음을 수집할 수 있습니다:

  • 시각화와 함께 쿼리 계획.
  • 실행 시간 및 프로덕션에 대한 예측.
  • Joe로부터 최적화에 대한 제안.
  • 메모리 및 IO 통계.

이러한 피드백을 받은 후에:

  1. 데이터 마이그레이션의 성능 문제를 조사할 수 있습니다.
  2. 수정된 코드를 푸시하면 위의 과정을 반복하고 최종적으로 데이터베이스 리뷰를 위해 내 Merge Request을 보낼 수 있습니다. 데이터베이스 리뷰 중에 리뷰어와 유지보수자는 소개된 변경사항의 성능에 대한 판단을 내리기 위해 모든 추가 생성된 정보를 사용할 수 있습니다.

이 정보 수집은 보호되고 안전한 환경에서 이루어지며, 기밀된 접근이 없도록 합니다. 우리는 이 환경에서 코드를 안전하게 실행할 수 있습니다.

계획된 이익에는 다음이 포함됩니다:

  • 왼쪽으로 이동: 개발자가 GitLab.com에서 일어날 대규모 데이터베이스 성능을 이해하고 셀프 서비스 방식으로 예상되는 것을 파악할 수 있도록 함
  • 일반적으로 프로덕션 규모 데이터세트에서만 생성되는 오류(불일치 또는 예상치 못한 패턴으로)를 식별
  • 적임자에게 자동으로 관련 세부사항을 제공하여 코드 리뷰에 참여하는 모든 사람(개발자, 리뷰어, 유지보수자)이 쉽게 할 수 있도록 정보 수집 단계를 자동화

기술 및 다음 단계

우리는 이미 postgres.ai의 Database Lab를 사용하고 있으며, 이는 얇게 복제 기술입니다. 우리는 프로덕션 데이터와 최신 상태의 PostgreSQL 레플리카를 유지하지만 프로덕션 트래픽은 제공하지 않습니다. 이것은 Database Lab를 운영하는 것으로, 프로덕션 데이터 세트의 완전한 복제본을 빠르게 생성할 수 있도록 합니다(초 단위로).

내부적으로 이는 ZFS를 기반으로 하며 “얇게 복제 기술”을 구현합니다. 즉, ZFS 스냅숏을 사용하여 데이터를 복제하고 이를 기반으로 한 완전한 읽기/쓰기 PostgreSQL 클러스터를 노출합니다. 이것을 “얇게 복제본”이라고 합니다. 이는 상대적으로 수명이 짧으며 우리가 사용을 마친 뒤에 곧 파괴됩니다.

얇은 복제본은 완전히 읽기/쓰기가 가능합니다. 이를 통해 우리는 이 위에 마이그레이션을 실행할 수 있습니다.

Database Lab은 우리가 얇게 복제한 데이터를 관리하기 위해 상호작용할 수 있는 API를 제공합니다. 마이그레이션 및 쿼리 테스트를 자동화하기 위해 gitlab/gitlab-org CI 파이프라인에 단계를 추가합니다. 이는 특정 Merge Request에 대해 다음 단계를 수행하는 자동화를 유발합니다:

  1. 이 테스트 세션을 위해 프로덕션 데이터의 얇은 복제본을 생성합니다.
  2. Merge Request으로부터 GitLab 코드를 가져옵니다.
  3. 마이그레이션을 실행하고 필요한 모든 정보를 수집합니다.
  4. 쿼리 테스트를 실행하고 필요한 모든 정보를 수집합니다.
  5. 마이그레이션 및 쿼리 테스트 결과를 Merge Request에 다시 전송합니다.
  6. 얇은 복제본을 파괴합니다.

단기

단기적인 초점은 주로 스키마 변경과 같은 일반적인 마이그레이션을 테스트하고 이미 존재하는 postgres.ai의 Database Lab 인스턴스를 사용하는 것에 있습니다.

이 프로세스를 보호하고 규정 목표를 달성하기 위하여 러너 환경은 프로덕션 환경으로 다루어지고 마찬가지로 잠금 처리되어 감시되며 감사됩니다. 데이터베이스 유지자만이 CI 파이프라인과 그 작업 출력에 액세스할 수 있습니다. 다른 모든 사람들은 Merge Request에 다시 전송된 결과 및 통계만 볼 수 있습니다.

내부적인 GitLab for Operations에 보호된 CI 파이프라인을 구현합니다. 이 파이프라인은 상기 실행 단계를 추가하는 것을 목표로 하고 있습니다.

다음 문제를 해결하기 위해 이 파이프라인을 보호합니다:

프로덕션 데이터를 강력하게 보호하고, 우리를 허락하더라도(깃랩 팀/개발자) 프로덕션 데이터가 포함된 얇은 복제본에서 임의의 코드를 실행할 수 있도록 합니다.

기본 원리는 코드를 실행하는 GitLab 러너 인스턴스와 해당 컨테이너가 외부로 데이터가 릴 때 방지하기 위해 네트워크 수준에서 잠그는 것입니다. 컨테이너 내부에서 외부로 통신할 수 없도록 하고, GitLab Rails 코드를 실행하는 컨테이너(및 해당 데이터베이스 마이그레이션)로부터 외부로 데이터가 유출되지 못하도록 확인합니다.

또한, 작업 결과를 확인할 수 있는 능력을 제한하여, 내부적인 GitLab for Operations 파이프라인의 유지자 및 소유자 수준만 볼 수 있도록 하고 원본 MR에는 분요한 요약만 제공합니다. 만일 작업 실행 중에 문제나 오류가 있으면, MR을 검토하기 위해 할당된 데이터베이스 유지자는 원본 작업의 세부사항을 확인할 수 있습니다.

이 단계를 구현하면 이미 얇게 복사한 GitLab.com 데이터베이스에서 GitLab CI를 통해 자동으로 데이터베이스 마이그레이션을 실행하고 Merge Request 및 개발자에게 피드백을 제공할 수 있습니다. 해당 피드백 내용은 시간이 지남에 따라 발전할 것으로 예상되며, 이러한 부분은 계속해서 추가할 수 있습니다.

현재 MVC 스타일로 구현된 파이프라인 및 파이프라인에서의 피드백을 포함한 예제 Merge Request이 이미 있습니다.

단기적인 목표는 이 에픽에서 상세히 설명되어 있습니다.

중간 기간 - 향상된 피드백, 쿼리 테스트 및 백그라운드 마이그레이션 테스트

중간 기간에는 테스트 파이프라인이 Merge Request에 다시 보고하는 세부 수준을 확대하고 쿼리 테스트도 포함하여 범위를 확대할 계획입니다. 이를 통해 데이터베이스 코드 리뷰와 가벼운 클론 기술 사용 경험을 활용하여 GitLab 작업 흐름에 가깝게 가져올 것입니다. 우리는 다양한 도구(postgres.ai, joe, Slack, 계획 시각화 등)에 접근하는 대신 이를 GitLab로 가져와 Merge Request에 직접 작업할 것입니다.

둘째로, 백그라운드 마이그레이션 테스트도 포함할 계획입니다. 이는 일반적으로 오랜 기간 동안 실행되는 데이터 마이그레이션으로, 스케줄링 단계와 작업 실행 단계의 성공은 주로 데이터 분포에 많은 영향을 받습니다. 실제 프로덕션 데이터에서 이러한 마이그레이션을 실행할 때에만 드러나는데, 백그라운드 마이그레이션에 대해 자신감을 얻기 위해 다음의 피드백을 제공할 계획입니다:

  1. 스케줄링 단계 - 쿼리 통계 (예: 쿼리 실행 시간의 히스토그램), 작업 통계 (작업 수, 전체 기간 등), 배치 크기.
  2. 실행 단계 - 몇 가지 작업의 인스턴스를 예로 들어 쿼리 및 런타임 통계를 수집합니다.

장기 기간 - GitLab 제품에 통합

이를 GitLab 자체로 추출하여 기능을 토론할 수 있는 기회가 있습니다. 예를 들어, Merge Request에 쿼리 예제를 주석으로 달고 테스트 실행으로부터 수집한 피드백을 Merge Request 설명과 코멘트 대신 첫째 등급 시민으로 사용할 수 있게 될 수 있습니다. 우리는 이러한 아이디어를 초기 단계에서 사용되는 것으로 보고 경험을 제품에 다시 가져올 계획입니다.

논의된 대체 방안: 익명화

이 문제의 핵심에는 프로덕션 데이터 세트에서 (잠재적으로 임의의) 코드를 실행하는 것과 프로덕션 데이터가 제대로 보호되는지에 대한 우려가 있습니다. 위에서 논의한 접근 방식은 해당 코드의 출력물에 대한 액세스를 강력하게 제한함으로써 이 문제를 해결합니다.

우리가 논의하고 버린 대체 접근 방식은 “스크럽”과 익명화하는 것입니다. 이 아이디어는 데이터베이스에서 민감한 데이터를 제거하고 나온 데이터셋을 데이터베이스 테스트에 사용하는 것입니다. 이는 우리가 아이디어를 버리게 된 여러 가지 단점이 있습니다:

  • 익명화는 본질적으로 복잡합니다 - “스크럽된 클론”이 실제로 공개에서 작업할 만하다고 말할 수 있는 문제는 어려운 문제입니다. 다른 데이터 유형은 다른 익명화 기술을 필요로 할 수 있으며(예: JSON 필드 내부의 민감한 정보 익명화), 한 번에 한 개 속성에만 초점을 맞추는 것은 데이터셋이 완전히 익명화된 것을 보장하지 않습니다(예: 조인 공격 또는 타임스탬프를 사용하여 사용자의 활동으로 공개 프로필/프로젝트를 함께 사용하여 사용자를 식별 해제하는 것).
  • 익명화는 데이터베이스 스키마가 변경될 때마다 민감한 속성 집합을 추적하고 업데이트하는 추가 프로세스가 필요합니다. 이는 지속적인 유지보수와 보안 검토가 필요합니다.
  • 데이터를 “민감하다”고 주석을 달는 것은 오류가 발생하기 쉬우며, 잘못된 익명화 접근 방식이 데이터 유형에 사용되거나 민감한 속성을 실수로 표시하지 않으면 데이터 침해로 이어질 수 있습니다.
  • 스크러빙은 민감한 데이터 뿐만 아니라 데이터 분포도 수정하며, 마이그레이션과 쿼리의 성능에 큰 영향을 미칩니다.
  • 스크러빙은 데이터베이스 내용을 크게 변경하여 많은 데이터를 업데이트할 수 있으며, 데이터 저장 세부 사항이 다르게 되어(MVC 확대 등) 마이그레이션과 쿼리의 성능에 영향을 미칩니다.