Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby로 PostgreSQL 파티션을 나눈 테이블 관리

거대한 테이블에서 많은 데이터를 삭제하면 데이터베이스 성능이 저하될 수 있으므로 기본 PostgreSQL 데이터베이스에서 분할된 테이블을 사용하여 오래된 데이터를 효율적으로 만료합니다. 버전 10 이전에는 PostgreSQL에 분할된 테이블에 대한 기본 지원이 없었으므로 pg_partman 확장을 사용하여 분할을 구현했습니다. PostgreSQL의 테이블 상속을 사용하여 분할할 테이블의 자식 테이블을 만들고 부모 테이블이 아닌 자식 테이블에 데이터를 삽입하도록 트리거합니다. 이 확장은 우리에게 잘 작동했지만 단점이 있습니다. Amazon RDS를 사용할 때는 지원되지 않기 때문에 옵션이 아닙니다. 이제 PostgreSQL이 기본 파티션을 지원하므로 RDS를 사용할 수 있는 옵션을 갖도록 해당 확장을 삭제하는 방법에 대해 알아볼 때라고 생각했습니다.

파티셔닝 사용 사례는 매우 간단합니다. 시간을 기준으로 테이블을 파티셔닝하고 모든 파티션에 저장할 행 수와 유지 기간에 따라 매일, 매주 또는 매월 새 파티션을 생성합니다. 데이터. 파티션을 나눈 모든 테이블에는 created_at가 있습니다. 각 행을 저장하는 파티션을 결정하는 데 사용되는 열입니다. 예를 들어 다음과 같이 정의된 테이블이 있을 수 있습니다.

create table events (
  project_id integer,
  data jsonb,
  created_at timestamp
)
partition by range (created_at);

그리고 주간 파티션을 갖고 싶다면 다음과 같을 것입니다.

create table events_p2019_10_28 partition of events for values from ('2019-10-28') to ('2019-11-04');
create table events_p2019_11_04 partition of events for values from ('2019-11-04') to ('2019-11-11');

시간 기반 파티셔닝 방식을 사용하면 파티션 중 하나를 삭제하는 것만큼 간단하게 오래된 데이터를 삭제할 수 있습니다. 따라서 정기적인 유지 관리는 날짜 범위에 접근할 때 날짜 범위에 대한 새 파티션을 만들고 더 이상 원하지 않는 데이터가 포함된 이전 파티션을 삭제하는 것입니다. 유지 관리를 조금 더 쉽게 하기 위해 pg_partition_manager gem을 만들었습니다. 당연히 pg_partman 확장 프로그램을 사용한 경험에서 영감을 얻었습니다. 이 확장은 우리에게 큰 도움이 되었습니다.

위에서 설명한 이벤트 테이블과 파티션 구성표를 감안할 때 이 gem을 어떻게 사용하는지 살펴보겠습니다. 다음과 같은 스크립트 또는 레이크 작업을 만들 수 있습니다.

require "pg_partition_manager"

PgPartitionManager::Time.process([{parent_table: "public.events", period: "week", premake: 1, retain: 3}])

parent_table schema.table_name으로 정의됩니다. (public , 기본 스키마는 종종 Rails 개발자가 사용하게 되는 유일한 스키마입니다. period 일, 주 또는 월일 수 있습니다. premake를 사용하여 미리(현재 기간 이후) 생성할 테이블 수를 선택할 수 있습니다. , 그리고 retain을 사용하여 (현재 기간 이전) 유지하려는 테이블 수 . premake를 지정하지 않으면 gem은 기본적으로 4개의 테이블을 미리 생성합니다. , 그리고 retain을 지정하지 않으면 기본적으로 7일, 4주, 6개월 동안 데이터를 유지합니다. .

매일 cron 작업으로 해당 스크립트/작업을 호출하면 모든 준비가 완료됩니다. 필요에 따라 테이블을 만들고 삭제합니다.

모든 ActiveRecord 쿼리는 파티션되지 않은 테이블과 마찬가지로 작동하므로 코드에서 변경할 필요가 없습니다. 즉, Event.create , Event.where 등은 항상 그렇듯이 작동하며 PostgreSQL은 데이터를 삽입할 때 올바른 파티션에 데이터를 넣습니다. 데이터가 많은 경우 알 수 있는 한 가지 변경 사항이 있습니다. 그러나 created_at를 포함하면... 쿼리에서 PostgreSQL은 모든 파티션을 스캔할 필요가 없습니다. where 절에서 지정한 범위를 포함하는 파티션만 스캔할 수 있습니다.

요약하자면 만료 시 삭제하려는 시간 기반 데이터가 많은 경우 PostgreSQL 분할 테이블과 pg_partition_manager gem을 사용하여 앱을 만족스럽게 만드십시오. :)