테이블 및 색인 블로트는 진공 작업이 테이블에 대한 데이터 조작 언어 (DML) 속도를 따라가지 못할 때 발생합니다. 일부 테이블 및 색인 블로트는 트랜잭션에서 해당 공간을 재사용할 수 있으므로 불가피하며 일반적으로 허용됩니다. 심각한 블로트는 쿼리 시간 지연, I/O 증가, 공유 버퍼 및 캐시 사용량 감소, 스토리지 비용 증가와 같은 성능 문제를 일으킵니다.
블로트를 추정하는 가장 좋은 방법은 pgstattuple 모듈을 사용하는 것입니다. 하지만 확장 프로그램이 관계의 모든 페이지를 읽어야 하는 경우 pgstattuple를 사용하는 것이 덜 효율적입니다. pgstattuple를 사용할 수 없는 경우 다른 스크립트를 사용하여 블로트를 추정할 수 있지만 이 방법은 정확도가 떨어집니다.
pgstattuple 출력 읽기
pgstattuple를 사용하여 테이블 또는 색인의 실제 저장소 특성을 보고하면 출력이 다음 형식으로 표시됩니다.
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 7431888896
tuple_count | 66666666
tuple_len | 2796296271
tuple_percent | 37.63
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 3873153652
free_percent | 52.12
출력은 다음과 같습니다.
table_len(7431888896)- 테이블의 총 크기(바이트)입니다. 여기에는 모든 활성 튜플, 비활성 튜플, 여유 공간이 포함됩니다. 이 경우
large_table가 약 7,088GB를 차지합니다. tuple_count(66666666)- 표에 있는 활성 튜플(표시되고 활성 상태인 행)의 수를 나타냅니다. 테이블에는 약 6,600만 개의 활성 행이 포함되어 있습니다.
tuple_len(2796296271)- 모든 라이브 튜플의 총 길이(바이트)로, 약 2.6GB입니다.
tuple_percent(37.63)활성 튜플이 차지하는
table_len의 비율입니다. 다음과 같이 계산합니다.(
tuple_len/table_len) ∗ 100 = (2796296271/7431888896) ∗ 100 ≈37.63percent이 출력은 활성 데이터가 테이블의 디스크 공간 중 40% 미만을 사용하고 있음을 나타냅니다.
dead_tuple_count(0)비활성 튜플 수입니다. 업데이트 또는 삭제 후 vacuum 작업에서 아직 삭제하지 않은 행입니다.
0값은 테이블이 정리되어 있고 회수되기를 기다리는 데드 튜플이 없음을 의미합니다. 이는 테이블에서VACUUM또는 autovacuum이 효율적으로 실행되고 있음을 나타내는 경우가 많습니다.dead_tuple_len(0)모든 데드 튜플의 총 길이(바이트)입니다.
dead_tuple_count와 마찬가지로0값은 데드 행이 공간을 소비하지 않음을 의미합니다.dead_tuple_percent(0)비활성화된 튜플이 차지하는
table_len의 비율입니다. 다음과 같이 계산합니다.(
dead_tuple_len/table_len) ∗ 100 = (0/7431888896) ∗ 100 =0%free_space(3873153652)이 값은 테이블의 데이터 페이지에 있는 여유 공간의 크기를 나타냅니다. 테이블 확장이 필요 없이 새 삽입 또는 업데이트에 이 공간을 재사용할 수 있습니다. 이는 약 3.7GB의 여유 공간이 있음을 나타냅니다.
free_percent(52.12)이 값은 여유 공간인
table_len의 비율을 나타냅니다. 다음과 같이 계산합니다.(
free_space/table_len) ∗ 100 = (3873153652/7431888896) ∗ 100 ≈52.12%
쿼리를 사용하여 블로트 추정
시스템 카탈로그 테이블에 대한 쿼리를 사용하여 블로트를 추정할 수 있지만 이 방법은 pgstattuple와 같은 확장 프로그램을 사용하는 것보다 정확도가 떨어집니다. PostgreSQL 테이블 bloat 확인과 같은 스크립트를 사용하는 경우 테이블 통계가 최신 상태여야 합니다. 그렇지 않으면 추정치가 정확하지 않습니다.
쿼리의 출력을 pgstattuple 모듈과 비교하면 추정치는 비교할 수 있지만 블로트의 정확한 측정치는 아닙니다. SQL 쿼리는 PostgreSQL의 누적 통계 엔진을 사용하는 반면 모듈은 실제 데이터 페이지를 읽기 때문에 모듈이 여전히 블로트의 더 정확한 측정기입니다.
다음 예에서는 large_table이라는 테이블에 대해 PostgreSQL에서 테이블 블로트를 분석하는 두 가지 다른 방법의 출력을 비교합니다.
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 2475892736
tuple_count | 22000000
tuple_len | 922925931
tuple_percent | 37.28
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 1293696900
free_percent | 52.25
Vs.
-[ RECORD 1 ]+------------
databasename | postgres
schemaname | public
tablename | large_table
can_estimate | t
est_rows | 21965400
pct_bloat | 54
mb_bloat | 1269.24
table_mb | 2361.195
주소 블롯
다음과 같은 방법으로 블로트를 관리할 수 있으며 각 방법에는 장단점이 있으므로 신중한 계획이 필요합니다.
- 전체 청소를 실행합니다. 이 작업에는 vacuum 기간 동안 전체 테이블 잠금이 필요하며 다운타임이 필요합니다.
- 새 테이블로 데이터를 이동합니다. 이 메서드를 사용하려면 변경사항이 새 관계로 전송되지 않도록 테이블 변경사항을 중지해야 합니다.
pg_squeeze을 사용합니다. 이 확장 프로그램은 온라인에서 블로트를 완화합니다. 확장 프로그램은 섀도 테이블을 만들고 모든 데이터를 삽입한 다음, 부풀려진 테이블을 새로 생성된 부풀려지지 않은 테이블로 전환하는 마지막 단계까지 복제 슬롯을 사용하여 테이블 변경사항을 유지합니다. 그런 다음 부풀려지지 않은 테이블을 이동하여 부풀려진 테이블을 대체하기 위해 간단한 테이블 잠금을 요청합니다. 이 메서드는 작업 기간 동안 객체 공간의 두 배가 필요하지만 정상 작동에 가장 적게 영향을 미칩니다.