진공 / 자동 진공 작동에는 시간이 얼마나 걸립니까? 16 기가

다양한 역할을 가진 테이블을 포함하는 큰 데이터베이스 (수백 개의 기가)를 관리하고 일부는 수백만 개의 레코드를 보유합니다. 일부 테이블은 많은 수의 삽입 및 삭제, 다른 일부는 삽입 및 업데이트 만받습니다.

데이터베이스는 16 기가 바이트의 RAM이있는 Debian 6.0 amd64 시스템의 PostgreSQL 8.4에서 실행됩니다.

문제는 때때로 테이블의 자동 진공 프로세스이므로 완료하는 데 시간이 오래 걸립니다 (일). 특정 진공 명령에 소요되는 시간을 대략적으로 알려주고 취소 여부를 결정할 수 있기를 원합니다. 또한 postgres 진공 작업에 대한 진행률 표시기가 있으면 실제로 도움이 될 것입니다.

편집하다:

방탄 솔루션을 찾고 있지 않습니다. 데드 튜플 수 또는 필요한 I / O 바이트 수에 대한 대략적인 힌트만으로도 충분합니다. 언제 끝날지 전혀 알지 못하는 것은 정말 성가신 VACUUM일입니다.

나는 pg_catalog.pg_stat_all_tables죽은 튜플의 수에 대한 열 이 있음을 보았습니다 . 따라서 ANALYZE이전에 테이블에 있어야한다는 것을 의미하더라도 추정값을 가질 수 있습니다 . 반면에, autovacuum_vacuum_thresholdautovacuum_vacuum_scale_factor설정을 혼자 자체가 포스트 그레스 증명 알고 테이블에 변화의 양에 대해 뭔가를 아마 너무 DBA의 손에 넣습니다.

실행할 때 쿼리를 확실하지 않습니다. 왜냐하면을 실행할 때 VACUUM VERBOSE테이블뿐만 아니라 테이블의 인덱스도 처리되고 있기 때문입니다.



답변

PostgreSQL (8.3) 에서이 트릭을 사용합니다.

  1. 사용하여 테이블의 디스크 크기를 얻습니다. pg_total_relation_size()여기에는 인덱스와 TOAST 크기가 포함 VACUUM됩니다. 이것은 얼마나 많은 바이트 VACUUM를 읽어야 하는지에 대한 아이디어를 제공합니다 .
  2. 나는 VACUUM테이블 위에서 뛰었다.
  3. 나는 발견 pidVACUUM과정을 (투입을 pg_catalog.pg_stat_activity).
  4. 리눅스 쉘에서 나는 pid가있는 while true; do cat /proc/123/io | grep read_bytes; sleep 60; done곳에서 실행 123한다-이것은 지금까지 디스크에서 프로세스가 읽은 바이트를 보여준다.

이것은 1 분마다 얼마나 많은 바이트가 처리 (읽기)되는지 대략적인 아이디어를 제공합니다 VACUUM. 필자 VACUUM는 1 단계에서 알고있는 디스크 크기의 전체 테이블 (인덱스 및 TOAST 포함)을 읽어야 한다고 가정합니다 .

필자는 테이블이 대부분 디스크에서 읽어야하므로 (Postgres 공유 메모리에는 없음) read_bytes필드가 진행 카운터로 사용될 수있을 정도로 충분하다고 가정합니다.

이 작업을 수행 할 때마다 프로세스에서 읽은 총 바이트 수는 전체 관계 크기의 5 %를 넘지 않으므로이 방법으로 충분할 수 있습니다.


답변

이것은 결정하기가 매우 어렵습니다. 자동 진공 청소기 를보다 공격적 이거나 온화하게 조정할 수 있습니다 . 그러나 약하게 설정하고 뒤쳐지고 기본 I / O로드가 너무 높으면 적절한 진공 상태에 도달하지 못할 수 있습니다. 그러면 프로세스가 실행 및 실행되고있는 것을 볼 수 있습니다. 또한, PostreSQL 이후 버전에서는 자동 진공 기능이 크게 향상되었으므로이 기능만으로도 그 중 하나로 이동할 수 있습니다 (가장 최신 버전 인 9.2).

진행률 표시 줄은 좋은 생각이지만, 의미있게 구현하기가 쉽지 않다고 생각합니다. 테이블에 일정한로드가있을 때 진행 상황이 거꾸로 진행되고있을 가능성이 있습니다 (죽은 행 수 / 백분율이 감소하는 대신 증가하는 것을 의미합니다). 어떤 결론을 이끌어 냅니까?


답변

우리 프로덕션에서 가장 큰 테이블 중 하나에 다음과 같은 로그가있었습니다.

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

이것은 지금까지 최악의 자원 소비이며 다른 모든 테이블은 2 초 미만을 차지했습니다.

이러한 유형의 로그를 보려면 다음을 실행해야합니다.

alter system set log_autovacuum_min_duration TO 5; 

(5ms 동안) 구성 파일을 다시로드하십시오.


답변

내가 찾은 이 게시물이 게시물에 도움을하지만, 다른 사람이 언급 한 것처럼,이 프로세스는 몇 가지 별도의 작업을 포함하기 때문에, 진공의 전체 진행을 계산하기 어려울 수 있습니다.

이 쿼리를 사용하여 진공 테이블 스캔 진행률을 모니터링합니다. 이는 대량 작업으로 보입니다.

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

그러나 여기에는 이후에 발생하는 인덱스 스캔이 포함되지 않으며 많은 인덱스가있는 경우 더 오래 걸리지 않을 수 있습니다. 불행히도 인덱스 검색 / 진공을 모니터링 할 방법이 없습니다.