pg_repack 확장을 사용하여 테이블 및 인덱스에서 부풀림을 줄입니다. - Amazon Relational Database Service

pg_repack 확장을 사용하여 테이블 및 인덱스에서 부풀림을 줄입니다.

pg_repack 확장을 사용하여 VACUUM FULL의 대안으로 표와 인덱스에서 팽창을 제거할 수 있습니다. 이 확장은 RDS for PostgreSQL 버전 9.6.3 이상에서 지원됩니다. pg_repack 확장 및 전체 표 재압축에 대한 자세한 내용은 GitHub 프로젝트 설명서를 참조하세요.

VACUUM FULL과 달리 pg_repack 확장에는 다음과 같은 경우 표 재구축 작업 중 짧은 기간 동안만 배타적 잠금(AccessExclusiveLock)이 필요합니다.

  • 로그 표 초기 생성 - 다음 예와 같이 데이터의 초기 복사 중에 발생하는 변경 사항을 기록하기 위해 로그 표가 생성됩니다.

    postgres=>\dt+ repack.log_* List of relations -[ RECORD 1 ]-+---------- Schema | repack Name | log_16490 Type | table Owner | postgres Persistence | permanent Access method | heap Size | 65 MB Description |
  • 최종 교체 및 삭제 단계.

나머지 재구축 작업의 경우 원래 표 행을 새 표로 복사하려면 원래 표에 ACCESS SHARE 잠금만 있으면 됩니다. 이렇게 하면 INSERT, UPDATE, DELETE 작업을 평소처럼 진행할 수 있습니다.

추천

pg_repack 확장을 사용하여 표와 색인에서 팽창을 제거할 때는 다음 권장 사항이 적용됩니다.

  • 업무 외 시간이나 유지 관리 기간 중에 재압축을 수행하여 다른 데이터베이스 활동의 성능에 미치는 영향을 최소화합니다.

  • 재구축 작업 중 차단 세션을 면밀히 모니터링하고 원래 표에 특히 배타적 잠금이 필요한 최종 교체 및 삭제 단계 중 pg_repack을 차단할 수 있는 작업이 없는지 확인합니다. 자세한 내용은 쿼리를 차단하는 요소 식별을 참조하세요.

    차단 세션이 표시되면 신중하게 고려한 후 다음 명령을 사용하여 세션을 종료할 수 있습니다. 이를 통해 pg_repack을 계속하여 재구축을 완료하는 데 도움이 됩니다.

    SELECT pg_terminate_backend(pid);
  • 트랜잭션 비율이 매우 높은 시스템에서 pg_repack's 로그 표의 누적된 변경 사항을 적용하는 동안 적용 프로세스가 변경 속도를 따라가지 못할 수 있습니다. 이 경우 pg_repack에서 적용 프로세스를 완료할 수 없습니다. 자세한 내용은 재압축 중 새 표 모니터링 단원을 참조하십시오. 인덱스가 심하게 팽창된 경우 다른 해결 방법은 인덱스 전용 재압축을 수행하는 것입니다. 이는 또한 VACUUM의 인덱스 정리 주기를 더 빠르게 완료하는 데도 도움이 됩니다.

    PostgreSQL 버전 12의 수동 VACUUM을 사용하면 인덱스 정리 단계를 건너뛸 수 있으며, PostgreSQL 버전 14의 긴급 autovacuum 중에는 인덱스 정리 단계를 자동으로 건너뛸 수 있습니다. 이렇게 하면 인덱스 팽창을 제거하지 않고도 VACUUM을 더 빠르게 완료할 수 있습니다. 이는 랩어라운드 VACUUM 방지와 같은 긴급 상황에만 사용 가능합니다. 자세한 내용은 Amazon Aurora 사용 설명서의 인덱스 팽창 방지를 참조하세요.

필수 조건

  • 표에는 PRIMARY KEY 또는 null이 아닌 UNIQUE 제약 조건이 있어야 합니다.

  • 확장 버전은 클라이언트와 서버 모두 동일해야 합니다.

  • RDS 인스턴스에 팽창이 없는 표의 전체 크기보다 더 많은 FreeStorageSpace가 있는지 확인합니다. 예를 들어, TOAST와 인덱스를 포함한 표의 총 크기를 2TB로, 표의 총 팽창을 1TB로 가정해 보겠습니다. 필요한 FreeStorageSpace는 다음 계산에서 반환된 값보다 커야 합니다.

    2TB (Table size) - 1TB (Table bloat) = 1TB

    다음 쿼리를 사용하여 표의 전체 크기를 확인하고 pgstattuple을 사용하여 팽창을 도출할 수 있습니다. 자세한 내용은 Amazon Aurora 사용 설명서의 표 및 인덱스 팽창 진단을 참조하세요.

    SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;

    이 스페이스는 활동 완료 후 회수됩니다.

  • RDS 인스턴스에 재압축 작업을 처리할 수 있는 충분한 컴퓨팅 및 IO 용량이 있는지 확인합니다. 최적의 성능 균형을 보장하려면 인스턴스 클래스를 확장하는 방안을 고려할 수 있습니다.

pg_repack 확장을 사용하려면
  1. 다음 명령을 실행하여 RDS for PostgreSQL 인스턴스에 pg_repack 확장을 설치합니다.

    CREATE EXTENSION pg_repack;
  2. 다음 명령을 실행하여 pg_repack에서 생성한 임시 로그 표에 대한 쓰기 액세스 권한을 부여합니다.

    ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC; ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
  3. pg_repack 클라이언트 유틸리티를 사용하여 데이터베이스에 연결합니다. rds_superuser 권한이 있는 계정을 사용합니다. 예를 들어 rds_test 역할이 rds_superuser 권한을 가지고 있다고 가정하겠습니다. 다음 구문은 postgres 데이터베이스의 모든 표 인덱스를 포함하는 전체 표에 대해 pg_repack을 수행합니다.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
    참고

    -k 옵션을 사용하여 연결해야 합니다. -a 옵션은 지원되지 않습니다.

    pg_repack 클라이언트의 응답은 재압축된 DB 인스턴스상의 표에 대한 정보를 제공합니다.

    INFO: repacking table "pgbench_tellers" INFO: repacking table "pgbench_accounts" INFO: repacking table "pgbench_branches"
  4. 다음 구문은 postgres 데이터베이스의 인덱스를 포함한 단일 표 orders를 재압축합니다.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres

    다음 구문은 postgres 데이터베이스의 orders 표에 대한 인덱스만 재압축합니다.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres

재압축 중 새 표 모니터링

  • 데이터베이스 크기는 교체 및 삭제 재압축 단계까지 표의 전체 크기에서 팽창을 뺀 값만큼 증가합니다. 데이터베이스 크기의 증가율을 모니터링하고, 재압축 속도를 계산하고, 초기 데이터 전송을 완료하는 데 걸리는 시간을 대략적으로 예측할 수 있습니다.

    예를 들어, 표의 총 크기를 2TB로, 데이터베이스의 크기를 4TB로, 표의 총 팽창을 1TB로 가정해 보겠습니다. 재압축 작업 종료 시 계산의 결과로 반환되는 데이터베이스 총 크기 값은 다음과 같습니다.

    2TB (Table size) + 4 TB (Database size) - 1TB (Table bloat) = 5TB

    두 시점 사이의 증가율(바이트)을 샘플링하여 재압축 작업의 속도를 대략적으로 추정할 수 있습니다. 증가율이 분당 1GB인 경우 초기 표 구축 작업을 완료하는 데 약 1,000분 또는 약 16.6시간이 걸릴 수 있습니다. 초기 표 구축 외에도 pg_repack에서는 누적된 변경 사항을 적용해야 합니다. 소요 시간은 진행 중인 변경 사항과 누적 변경 사항을 적용하는 속도에 따라 달라집니다.

    참고

    pgstattuple 확장을 사용하여 표의 팽창을 계산할 수 있습니다. 자세한 내용은 pgstattuple을 참조하세요.

  • 재압축 스키마 아래에 있는 pg_repack's 로그 표의 행 수는 초기 로드 후 새 표에 적용하기 위해 보류 중인 변경 사항의 양을 나타냅니다.

    pg_stat_all_tables에서 pg_repack's 로그 표를 확인하여 새 표에 적용된 변경 사항을 모니터링할 수 있습니다. pg_stat_all_tables.n_live_tup은 새 표에 적용할 보류 중인 레코드 수를 나타냅니다. 자세한 내용은 pg_stat_all_tables를 참조하세요.

    postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%'; -[ RECORD 1 ]--------- relname | log_16490 n_live_tup | 2000000
  • pg_stat_statements 확장을 사용하여 재압축 작업의 각 단계에 소요된 시간을 확인할 수 있습니다. 이는 프로덕션 환경에서 동일한 재압축 작업을 적용할 준비를 하는 데 유용합니다. LIMIT 절을 조정하여 출력을 더 확장할 수 있습니다.

    postgres=>SELECT SUBSTR(query, 1, 100) query, round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes FROM pg_stat_statements WHERE query ILIKE '%repack%' ORDER BY total_exec_time DESC LIMIT 5; query | total_exec_time_in_minutes -----------------------------------------------------------------------+---------------------------- CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) | 6.8627 INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1 | 6.4150 SELECT repack.repack_apply($1, $2, $3, $4, $5, $6) | 0.5395 SELECT repack.repack_drop($1, $2) | 0.0004 SELECT repack.repack_swap($1) | 0.0004 (5 rows)

재압축은 부적절한 작업이므로, 원본 표는 영향을 받지 않으며 원본 표를 복구해야 하는 예상치 못한 문제가 발생하지 않습니다. 재압축이 예기치 않게 실패할 경우 오류의 원인을 검사하여 해결해야 합니다.

문제가 해결되면 표가 있는 데이터베이스에서 pg_repack 확장을 삭제하고 다시 만든 다음 pg_repack 단계를 다시 시도하세요. 또한 컴퓨팅 리소스의 가용성과 표의 동시 접근성은 재압축 작업을 적시에 완료하는 데 중요한 역할을 합니다.