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
proposed @mattkasa @jon_jenkins @DylanGriffith @rogerwoo @alexives devops data stores 2023-02-08

자동화된 쿼리 분석

문제 개요

우리의 총 목표는 GitLab 데이터베이스 검토 프로세스의 신뢰성과 처리량을 향상시키는 것입니다. 현재 프로세스는 Merge Request 작성자가 새로운 쿼리를 도입하거나 기존 쿼리를 업데이트할 때 쿼리 계획 및 원시 SQL을 매뉴얼으로 제공해야 합니다. 이는 시간이 많이 소요되며 오류가 발생할 가능성이 있습니다.

우리는 신규 도입된 SQL 쿼리를 자동으로 식별하고 분석함으로써 운영 효율성을 향상시킬 수 있다고 믿습니다. 이는 인간의 오류 위험을 줄이고 시스템 안정성을 향상시키고 성능 하락을 전반적으로 줄일 것입니다.

우리의 주요 성공 지표는 코드 기여자 및 데이터베이스 검토자가 수행해야 하는 매뉴얼 작업의 감소이며, 동시에 데이터베이스 관련 코드 기여에 대한 일관된 표준을 유지하는 것입니다.

목표

  1. 현재의 작업자가 매뉴얼으로 SQL과 쿼리 계획을 얻는 과정을 자동화합니다.
  2. 매뉴얼 작업으로 놓칠 수 있는 성능 하락 사례를 줄입니다.
  3. 데이터베이스 검토에서의 쿼리 테스트 부분을 자동화함으로써 기여자 및 검토자의 효율성을 높입니다.

도전과제

  • gitlab-org/gitlab와 같은 규모의 애플리케이션이 생성하는 SQL 쿼리 수를 캡처할 때 CI 시간 및/또는 리소스 증가를 유발하지 않으면서 캡처하는 것은 도전이 될 수 있습니다.
  • gitlab-org/gitlab과 같은 규모의 애플리케이션이 생성하는 SQL 쿼리 수를 저장하는 것은 많은 양의 데이터베이스 저장 공간을 소비할 수 있습니다.

기회

  • 자동 테스트 스위트에서는 이미 메트릭 가능한 수의 SQL 쿼리를 생성하고 있으며, 예를 들어 rspec 테스트 스위트가 그것일 수 있습니다. 이러한 쿼리를 캡처하여 자동 분석에 사용할 수 있습니다.
  • 우리는 이미 쿼리 성능을 분석하는 데 postgres.ai를 활용하고 있으며, 실제 프로덕션과 유사한 데이터를 사용하여 데이터베이스 클론을 자동으로 생성할 수 있는 해당 API가 있습니다.
  • postgres.ai와 같은 것을 사용하지 않는 고객은 CI에서 테스트 데이터베이스에 연결되지만, 이 연결을 사용하여 쿼리 계획을 생성할 것입니다. 이러한 쿼리 계획의 정확성은 테스트 데이터의 현실성에 영향을 받으며, 테스트 데이터베이스에 실제 프로덕션과 유사한 데이터를 시드할 수 있습니다.
  • 쿼리 및 해당 쿼리 계획을 저장함으로써 쿼리 계획을 계획 컴포넌트로 토큰화하고 비용 및 가중치를 할당한 다음, 이를 기계 학습 모델에 일치시킬 수 있습니다. 우리는 느린 쿼리 로그에서 쿼리 계획의 쿼리와 실제 비용 및 가중치를 할당하여 이 모델을 구축할 수 있습니다. 이를 통해 임의의 쿼리 텍스트의 성능을 예측하기 위해 쿼리와 느린 쿼리 로그의 코퍼스를 활용할 수 있습니다.

제안

우리는 신규와 변경된 데이터베이스 쿼리를 식별하는 프로세스를 자동화하여 코드 기여자와 검토자가 코드 변경의 데이터베이스 성능 영향을 보다 정확하게 평가하고 효율적으로 할 수 있도록 계획하고 있습니다.

우리는 CI에서 테스트를 실행하는 부수적인 효과로 생성된 쿼리를 캡처하고 이를 정규화하고 중복을 제거한 후 하나 이상의 분석기를 사용하여 분석하고 그들의 분석 및 기타 메타데이터와 함께 보관하여 나중에 검색하고 비교할 수 있도록 합니다.

우리는 원본 Merge Request에 새로운 및 변경된 쿼리를 요약하고 그것들의 분석에 대한 링크와 성능 가이드라인을 초과하는 쿼리를 강조하는 코멘트를 게시할 것입니다.

디자인 및 구현 세부 정보

반복 1

첫 번째 반복에서는 쿼리를 어떻게 캡처하는지에 중점을 두고 있습니다. 이는 정규화, 중복 제거 및 저장을 포함합니다. 우리는 캡처 과정 중 CI 파이프라인에 미치는 성능 및 리소스 영향을 제한하기 위해 노력할 것입니다. 다음은 쿼리를 캡처하기 위해 고려할 몇 가지 옵션입니다.

쿼리 캡처

우리는 CI 파이프라인에 미치는 시간과 리소스 영향을 최대한 제한하기 위해 다음과 같은 캡처 옵션을 고려할 것입니다.

  • rubyActiveRecord 에 기구화
    • 도전과제:
      • ruby 프로젝트에만 적용되므로 container-registry와 같은 프로젝트에는 적용되지 않을 수 있습니다.
      • CI 파이프라인에서 시간과 리소스에 영향을 미칠 수 있습니다(이러한 영향은 !111638에서 관찰할 수 있음).
    • 기회:
      • 간단하고 직접적으로 구현할 수 있습니다.
      • 더 많은 정보(예: 스택 추적 및 호출 위치)에 액세스할 수 있습니다.
  • 로깅을 통한 연결 프록시
    • 도전과제:
      • 추가 복잡성 및 가능한 성능 부하가 발생할 수 있습니다.
      • 프록시 코드를 유지해야 합니다.
    • 기회:
      • 캡처를 사용자 정의할 수 있습니다.
      • 캡처 시 정규화/중복 제거를 수행할 수 있습니다.
  • postgresql 내장 로깅
    • 도전과제:
      • 로깅을 활성화하기 위한 구성 추가가 필요할 수 있습니다.
      • 결과 로그를 얻는 것이 어려울 수 있습니다.
    • 기회:
      • 코드를 유지할 필요가 없습니다.
      • 성능 측면에서 가벼움.
  • pg_stat_statements로부터 캡처
    • 도전과제:
      • 테스트 데이터베이스에 확장을 생성해야 합니다.
      • pg_stat_statements.max를 캡처할 값으로 설정하는 구성을 추가해야 합니다.
      • pg_stat_statements.max에 비례한 공유 메모리를 소비합니다.
    • 기회:
      • 코드가 최소한으로 필요합니다.
      • 데이터를 얻는 것이 간단합니다.
      • 데이터는 이미 정규화되어 있습니다.

우리는 이미 !111638에서 rubyActiveRecord를 기구화하는 것에 대한 증명을 완성했으므로 먼저 이를 기준으로 다른 캡처 방법을 벤치마크하고 최적의 옵션을 선택할 것입니다.

쿼리 저장

첫 번째 반복의 다음 단계로, !111638의 PoC를 사용하며 다른 캡처 방법을 테스트하는 데 수집된 데이터를 사용하여 프로젝트당 행 수를 추정하고 gitlab-org/gitlab의 파이프라인 실행 통계를 사용하여 처리량을 추정할 것입니다. 이러한 추정값을 사용하여 목적에 적합한 저장 메커니즘을 평가할 수 있게 될 것입니다.

우리가 평가할 몇 가지 저장 메커니즘은 다음과 같습니다.

  • GitLab 데이터베이스 인스턴스의 ci 데이터베이스 안에
    • 도전과제:
      • GitLab.com에 대한 이 리소스에 추가적인 부담을 가합니다.
    • 기회:
      • CI_JOB_TOKEN 형태의 기존 인증 및 액세스 제어를 활용할 수 있습니다.
      • ci_buildsci_pipelines과의 연관을 활용할 수 있습니다.
      • 자기 관리를 위한 배포를 단순화합니다.
  • GitLab 데이터베이스 인스턴스의 새로운 분해된 데이터베이스 안에
    • 도전과제:
      • 필요한 개발 및 테스트 노력이 추가됩니다.
      • GitLab.com에 대한 배포 노력이 추가됩니다.
    • 기회:
      • 기존 mainci 데이터베이스 인스턴스로부터 데이터베이스 성능 영향을 분리합니다.
  • 새로운 외부 서비스 안에
    • 도전과제:
      • 필요한 개발 및 테스트 노력이 추가됩니다.
      • GitLab.com 및 Self-Managed형를 위한 배포 노력이 추가됩니다.
    • 기회:
      • gitlab-org/gitlab의 성능 영향을 분리합니다.
      • 기본 응용 프로그램에 영향을 미치지 않고 더 빨리 반복할 수 있게 됩니다.
  • ClickHouse에
    • 도전과제:
      • Self-Managed형를 위해 아직 사용할 수 없습니다.
    • 기회:
      • 기존 mainci 데이터베이스 인스턴스로부터 데이터베이스 성능 영향을 분리합니다.

쿼리를 저장하기 위한 한 가지 예시 데이터베이스 스키마는 다음과 같습니다.

CREATE TABLE queries (
    created_at timestamp with time zone NOT NULL,
    updated_at timestamp with time zone NOT NULL,
    id bigint NOT NULL,
    project_id bigint NOT NULL,
    analysis_id bigint,
    hash text,
    sql text
);
CREATE TABLE pipeline_queries (
    id bigint NOT NULL,
    project_id bigint NOT NULL,
    pipeline_id bigint NOT NULL,
    query_id bigint NOT NULL
);
CREATE TABLE analyses (
    created_at timestamp with time zone NOT NULL,
    updated_at timestamp with time zone NOT NULL,
    id bigint NOT NULL,
    project_id bigint NOT NULL,
    query_id bigint NOT NULL,
    buffers int,
    walltime int,
    explain text,
    analysis_url text
);

위와 같은 예시 스키마를 부분 파티셔닝으로 활용할 수 있는 한 가지 방법은 서브-파티션을 활용하는 것입니다. 만약 project_id로 파티셔닝한 다음 updated_at의 일정한 간격으로 파티셔닝하고 쿼리 실행을 볼 때 행을 터치하면 코드베이스가 여전히 실행 중인 쿼리만을 저장하고 더는 생성되지 않는 쿼리만을 포함하는 파티션을 정리할 수 있게 됩니다.

이터레이션 2

두 번째 이터레이션에서는 새로 식별된 쿼리와 변경된 쿼리를 식별하고 MR(Merge Request)에 해당 내용을 요약한 코멘트를 게시할 계획입니다. 우리는 정보의 정확성과 유용성에 대한 피드백을 구체화하고, 그 유용성을 극대화하기 위해 개선하거나 걸러내기 시작할 것입니다.

이터레이션 3+

세 번째 이터레이션부터는 하나 이상의 분석기를 사용하여 쿼리 분석을 자동화하고, 이러한 분석 결과를 저장하고 MR 코멘트에 추가할 계획입니다. 또한 쿼리 정보를 저장하는 데이터베이스와 해당 정보를 검색하는 API의 사용을 재평가하고, 이를 외부 서비스로 이전하는 것도 고려할 예정입니다.