내 질문에는 두 부분이 있습니다.
- PostgreSQL에서 데이터베이스의 초기 크기를 지정하는 방법이 있습니까?
- 그렇지 않은 경우 시간이 지남에 따라 데이터베이스가 커질 때 조각화를 어떻게 처리합니까?
최근에 MSSQL에서 Postgres로 마이그레이션했으며 데이터베이스를 만들 때 MSSQL 세계에서 한 일 중 하나는 데이터베이스 및 트랜잭션 로그의 초기 크기를 지정하는 것이 었습니다. 이는 특히 데이터베이스의 "정상"크기를 미리 알고있는 경우 조각화를 줄이고 성능을 향상 시켰습니다.
크기가 커질수록 데이터베이스 성능이 떨어집니다. 예를 들어, 내가 수행하는 작업량은 보통 10 분이 걸립니다. 데이터베이스가 커지면이 시간이 늘어납니다. VACUUM, VACUUM FULL 및 VACUUM FULL ANALYZE를 수행해도 문제가 해결되지 않습니다. 성능 문제를 해결하는 것은 데이터베이스를 중지하고 드라이브를 조각 모음 한 다음 VACUUM FULL ANALYZE를 수행하면 테스트 성능이 원래 10 분으로 되돌아갑니다. 이것은 파편화가 나를 고통스럽게 만드는 원인으로 의심됩니다.
Postgres에서 테이블 공간 / 데이터베이스 공간 예약에 대한 참조를 찾을 수 없었습니다. 잘못된 용어를 사용하여 아무것도 찾지 못하거나 Postgres에서 파일 시스템 조각화를 완화하는 다른 방법이 있습니다.
어떤 포인터?
해결책
제공된 답변은 내가 의심하기 시작한 것을 확인하는 데 도움이되었습니다. PostgreSQL은 데이터베이스를 여러 파일에 저장하므로 조각화 걱정없이 데이터베이스를 확장 할 수 있습니다. 기본 동작은 이러한 파일을 테이블 데이터가있는 가장자리에 묶는 것입니다. 테이블 데이터는 거의 변경되지 않지만 자주 업데이트되는 테이블에는 적합하지 않습니다.
PostgreSQL은 MVCC 를 사용하여 테이블 데이터에 대한 동시 액세스를 제공합니다. 이 체계에서 각 업데이트는 업데이트 된 새로운 버전 의 행을 만듭니다 (이것은 타임 스탬프 또는 버전 번호를 통해 알 수 있습니까?). 이전 데이터는 즉시 삭제되지 않지만 삭제 표시됩니다. 실제 삭제는 VACUUM 작업이 수행 될 때 발생합니다.
이것은 채우기 비율과 어떤 관련이 있습니까? 테이블 기본 채우기 비율 100은 테이블 페이지를 완전히 압축하므로 테이블 페이지 내에 업데이트 된 행을 보유 할 공간이 없습니다. 즉, 업데이트 된 행은 원래 행과 다른 테이블 페이지에 배치됩니다. 내 경험이 보여주는 것처럼 성능이 좋지 않습니다. 요약 테이블이 매우 자주 업데이트 될 때 (최대 1500 행 / 초) 채우기 비율을 20으로 설정했습니다. 즉, 테이블의 20 %는 삽입 된 행 데이터에, 80 %는 업데이트 데이터에 사용됩니다. 이것이 과도하게 보일 수 있지만 업데이트 된 행에 예약 된 대량의 공간은 업데이트 된 행이 원본과 동일한 페이지 내에 유지되고 autovacuum 데몬이 사용되지 않는 행을 제거하기 위해 실행될 때까지 테이블 페이지가 가득 차지 않은 것을 의미합니다.
데이터베이스를 "수정"하기 위해 다음을 수행했습니다.
- 요약 테이블의 채우기 비율을 20으로 설정하십시오. 작성시 또는 CREATE TABLE에 매개 변수를 전달 하거나 ALTER TABLE을 통해 사실 이후에 이를 수행 할 수 있습니다 . 다음 plpgsql 명령을 실행했습니다.
ALTER TABLE "my_summary_table" SET (fillfactor = 20);
- VACUUM FULL을 발행했습니다. 완전히 새로운 버전의 테이블 파일을 작성하기 때문에 새로운 채우기 비율로 새로운 테이블 파일을 작성 합니다.
테스트를 실행하면 데이터베이스가 수백만 행에 필요한만큼 커도 성능이 저하되지 않습니다.
TL; DR-파일 조각화가 원인이 아니라 테이블 스페이스 조각화입니다. 이는 특정 사용 사례에 맞게 테이블의 채우기 비율을 조정하여 완화됩니다.