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


18

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

데이터베이스는 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테이블뿐만 아니라 테이블의 인덱스도 처리되고 있기 때문입니다.

답변:


34

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 %를 넘지 않으므로이 방법으로 충분할 수 있습니다.


Nasty :)이 기능은 이후 버전에서도 작동합니까? 그리고 더 중요한 것은 autovacuum?
dezso

최신 버전에서는 시도하지 않았습니다. VACUUM FULL테이블을 완전히 다시 작성하므로 9.0 이상에서 작동해야 합니다. 정기적으로 작동 VACUUM하지만 아직 테스트하지 않았습니다. 들어 autovacuum당신은 주어진 테이블에 자동 진공 작업자 프로세스를 잡을 수 있다면 그것이 작동,하지만 내가 이것을 달성하는 방법을 모르겠어요.
Roman Hocke

RDS로이를 달성하는 방법에 대한 제안 사항이 있습니까? 당연히 RDS를 사용할 때 리눅스 쉘에 액세스 할 수는 없지만 이것을 추정 할 수 있기를 바랍니다.
jwg2s

@ jwg2s "RDS"는 무엇을 의미합니까? 아마존의 데이터베이스 서비스? 그렇다면 불행히도 그것에 익숙하지 않습니다 :-( 아마도 그들의 지원이 도움이 될 것입니다.
Roman Hocke

1
진공이 가득 찬 상태에서 PG 10에서도 잘 작동하는 것 같습니다.
DylanYoung

9

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

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


2
나는 아무것도 진행하지 않고 오히려 뒤로 진행하더라도 진행률 표시기를 보는 것을 선호합니다.
zaadeh

3
VACUUM ANALYZE VERBOSE최소한 콘솔에 활동을 인쇄합니다. 그렇다면 몇 시간 동안 무언가가 붙어 있는지 궁금해하는 정적 프롬프트를 쳐다 보는 것이 좋습니다.
가짜 이름

질문은 "진공 / 자동 진공"에 대해 묻습니다. 위의 내용은 VACUUMautovacuum이 아닌 에만 유용 하지만 여전히 뭔가입니다.
가짜 이름

@ FakeName Eh, 나는 질문을 잘못 읽었습니다. 수동 진공 부분을 놓쳤습니다. 죄송합니다. 댓글을 삭제하고 있습니다.
dezso

3

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

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 동안) 구성 파일을 다시로드하십시오.


3

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

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

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;

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.