PostgreSQL에서 디스크 공간을 확보하는 방법?


25

cca가있는 테이블이 거의없는 9.1 데이터베이스의 로컬 설치가 있습니다. 300 개의 mio 레코드와 데이터베이스가 약 20GB로 증가했습니다. 그 후 delete from모든 레코드를 삭제하라는 명령을 내 렸습니다 (을 사용해야 truncate했지만 그 사실을 몰랐습니다). 따라서 디스크 공간을 확보하기 위해 DB를 완전히 진공 청소기로 청소했지만 도움이되지 않습니다. 내 문제는 동일 보이는 이것 만 제공 해결 방법이 없습니다. 디스크"디스크 공간 복구" 에 대한 문서를 이미 확인 했지만 여전히 해결책을 찾을 수 없습니다. 이 코드를 사용하여 모든 테이블의 크기를 얻습니다.

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

그러나 총 1GB 미만

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

여전히 약 20GB를 보여줍니다. 많은 조언을 부탁드립니다.


크기 쿼리는 인덱스, 테이블 pg_catalog및 테이블을 제외합니다 information_schema. 따라서 WHERE절 에서 이러한 제한을 제거하여 그 중 하나인지 확인하십시오 . 정확한 PostgreSQL 버전 ( SELECT version())과 "전체 데이터베이스를 진공 청소기로 청소"하기 위해 정확히 무엇을하고 있는지, 즉 정확한 명령을 표시하십시오. 가능하면 VACUUM FULL VERBOSE;(인수 없음)을 실행 하고 출력을 어딘가에 붙여 넣은 다음 여기에 연결하십시오.
Craig Ringer

데이터베이스를 삭제하십시오. 데이터베이스 덤프를 시도한 후 복원하면 가비지가 삭제됩니다.
jb.

1
@jb 작동하지만 필요하지는 않습니다. 문제가 무엇인지 배우는 것이 좋습니다.
Craig Ringer

답변:


22

명시하지는 않았지만 데이터베이스 및 / 또는 영향을받는 테이블에서 VACUUM FULL을 수행했다고 가정 한 문서를 참조한 것으로 가정합니다. 또한 사용중인 postgresql 버전을 지정하지 않았습니다.> 9.0 (VACUUM FULL 이전에 다르게 동작 함)이라고 가정하겠습니다.

VACUUM FULL 은 영향을받는 테이블을 새 파일로 다시 쓴 다음 이전 파일을 삭제합니다. 그러나 프로세스에 여전히 이전 파일이 열려 있으면 마지막 프로세스가 파일을 닫을 때까지 운영 체제가 실제로 파일을 삭제하지 않습니다.

가능하면 데이터베이스를 다시 시작하면 열려있는 모든 파일이 닫힙니다.

이것이 실용적이지 않다면 이것이 문제인지 확인하고 파일이 열려있는 프로세스를 찾을 수 있습니다.

Linux (또는 대부분의 다른 유닉스 계열 시스템)를 사용하는 경우 'lsof'명령을 사용하여 모든 프로세스에서 열려있는 모든 파일 목록을 가져올 수 있습니다. 열려 있지만 이후에 삭제 된 파일은 파일 이름에 '(삭제됨)'이 추가됩니다. 따라서 lsof의 출력을 grep하여 다음과 같이 삭제 된 파일을 찾을 수 있습니다.

sudo lsof -u postgres | grep 'deleted'

이전 파일이 여전히 열려있는 프로세스를 식별하는 경우 pg_terminate_backend를 사용하여 해당 프로세스를 종료 할 수 있습니다.

SELECT pg_terminate_backend(xxx);

여기서 xxx는 프로세스의 PID이며 lsof 출력에 있습니다.

Windows를 사용하는 경우 postgres가 FILE_SHARE_DELETE 플래그를 사용하여 파일을 열어 다른 프로세스에서 열린 파일을 삭제할 수 있기 때문에 동일한 원칙이 적용될 수 있습니다. ' handle '명령은 lsof와 대략 동일하지만 파일이 삭제되었는지 여부를 알 수 있는지 확실하지 않으므로 추가 작업이 필요할 수 있습니다.

그러한 프로세스가 왜 오래된 파일 핸들에 매달려 있는지에 대한 또 다른 질문입니다. 그러나 귀하의 질문에 인용 한 스레드 에서 Tom Lane은 그것이 일어날 수 있음을 암시하는 것처럼 보입니다.


데이터베이스를 삭제하고 백업에서 복원하기 위해 긴급히 디스크 공간을 확보해야했습니다. 그러나이 문제를 해결하는 "방법"은 앞으로의 경우에 여전히 가치가 있습니다. 내 데이터베이스는 9.1, 승리 8 64 비트이며 파일 이름 지정 (열린 파일의 경우)은 Linux와 동일한 방식으로 적용됩니까?

@arcull 좋아, 나는 당신이 Windows를 사용하고 있다는 것을 몰랐다. Windows에 어떻게 적용되는지에 대한 정보를 추가했습니다. 유용한 답변이라고 생각되면 다른 사람이 쉽게 찾을 수 있도록 상향 조정을 고려하십시오.
harmic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.