CI 데이터베이스에 새 테이블 추가
GitLab v19.1파이프라인 데이터 파티셔닝 설계 문서는 CI 도메인에서 기존 테이블을 파티셔닝하는 방법을 설명합니다. 데이터베이스 헬퍼를 사용하여 새 테이블과 외래 키를 생성하는 예시는 다음과 같습니다: 이 테이블은 라우팅 테이블이라고 하며 데이터를 보유하지 않습니다.
파이프라인 데이터 파티셔닝 설계 문서는 CI 도메인에서 기존 테이블을 파티셔닝하는 방법을 설명합니다.
그러나 새로운 기능을 위해서는 여전히 테이블을 추가해야 합니다.
때로는 이러한 테이블이 파티셔닝이 필요한 더 큰 테이블에 대한 참조를 보유하기도 합니다.
향후 작업을 줄이기 위해, 파티셔닝 가능한 테이블에 대한 belongs_to 연관을 사용하는 모든 테이블은 처음부터 파티셔닝되어야 합니다.
새 라우팅 테이블 생성#
데이터베이스 헬퍼를 사용하여 새 테이블과 외래 키를 생성하는 예시는 다음과 같습니다:
include Gitlab::Database::PartitioningMigrationHelpers
disable_ddl_transaction!
def up
create_table(:p_ci_examples, primary_key: [:id, :partition_id], options: 'PARTITION BY LIST (partition_id)', if_not_exists: true) do |t|
t.bigserial :id, null: false
t.bigint :partition_id, null: false
t.bigint :build_id, null: false
end
add_concurrent_partitioned_foreign_key(
:p_ci_examples, :p_ci_builds,
column: [:partition_id, :build_id],
target_column: [:partition_id, :id],
on_update: :cascade,
on_delete: :cascade
)
end
def down
drop_table :p_ci_examples
end
이 테이블은 라우팅 테이블이라고 하며 데이터를 보유하지 않습니다. 데이터는 파티션에 저장됩니다.
라우팅 테이블을 생성할 때:
-
테이블 이름은 반드시
p_접두사로 시작해야 합니다. 모든 쿼리가 라우팅 테이블을 통해 처리되고 파티션에 직접 액세스하지 않도록 보장하는 분석기가 있습니다. -
각 새 테이블에는
partition_id칼럼이 필요하며 그 값은 관련 연관에서의 값과 동일해야 합니다. 이 예시에서는p_ci_builds가 해당됩니다. 파이프라인에 속하는 모든 리소스는 동일한partition_id값을 공유합니다. -
기본 키는
id만으로 효율적인 검색을 허용하기 위해 칼럼 순서를 이 방식으로 지정해야 합니다. -
외래 키 제약 조건은 반드시
ON UPDATE CASCADE옵션을 포함해야 합니다. 파티션 재균형을 위해partition_id값을 업데이트할 수 있어야 하기 때문입니다.
첫 번째 파티션 생성#
일반적으로 애플리케이션이 부팅 시에 초기 파티션을 생성하도록 합니다. 그러나 CI 테이블의 높은 트래픽과 많은 노드 수로 인해 참조된 테이블에 대한 잠금을 획득하기 어려울 수 있습니다. 따라서 배포 중에 노드가 시작에 실패할 수 있습니다. 이러한 실패를 방지하려면 애플리케이션이 실행되기 전에 파티션이 이미 준비되어 있는지 확인해야 합니다:
disable_ddl_transaction!
def up
with_lock_retries do
connection.execute(<<~SQL)
LOCK TABLE p_ci_builds IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE ONLY p_ci_examples IN ACCESS EXCLUSIVE MODE;
SQL
connection.execute(<<~SQL)
CREATE TABLE IF NOT EXISTS gitlab_partitions_dynamic.ci_examples_100
PARTITION OF p_ci_examples
FOR VALUES IN (100);
SQL
end
end
파티션은 gitlab_partitions_dynamic 스키마에 생성됩니다.
파티션을 생성할 때 다음 사항을 기억하세요:
-
파티션 이름에는
p_접두사를 사용하지 않습니다. -
partition_id의 시작 값은100입니다.
파티션 값 계단식 전파#
파티션 값을 계단식으로 전파하려면 모듈이 Ci::Partitionable 모듈을 사용해야 합니다:
class Ci::Example < Ci::ApplicationRecord
include Ci::Partitionable
self.table_name = :p_ci_examples
self.primary_key = :id
belongs_to :build, class_name: 'Ci::Build'
partitionable scope: :build, partitioned: true
end
파티션 관리#
모델은 PARTITIONABLE_MODELS 목록에 포함되어야 합니다.
이 목록은 partition_id가 올바르게 전파되는지 테스트하는 데 사용됩니다.
목록에서 누락된 경우, partitioned: true를 지정하면 첫 번째 파티션이 생성됩니다.
모델은 또한 postgres_partitioning.rb 이니셜라이저에도 등록되어야 합니다.