사용 가능한 디스크 공간없이 VACUUM FULL을 실행해야합니다.


27

서버에서 HD 공간의 약 90 %를 차지하는 테이블이 하나 있습니다. 공간을 확보하기 위해 몇 개의 열을 삭제하기로 결정했습니다. 그러나 공간을 OS로 되돌려 야합니다. 그러나 문제는 VACUUM FULL을 실행하고 테이블 사본을 만들 수있는 충분한 여유 공간이없는 경우 어떻게 될지 확실하지 않다는 것입니다.

VACUUM FULL을 사용해서는 안된다는 것을 이해하지만이 시나리오에서는 이것이 최선의 선택이라고 생각했습니다.

모든 아이디어를 부탁드립니다.

PostgreSQL 9.0.6을 사용하고 있습니다

답변:


19

vacumm을 실행하거나 재 구축 할 공간이 충분하지 않으므로 postgresql 데이터베이스를 복원하여 언제든지 재 구축 할 수 있습니다. 데이터베이스, 테이블, 인덱스를 복원하면 공간과 조각 모음이 해제됩니다. 그런 다음 자동 유지 관리를 설정하여 데이터베이스를 정기적으로 비워 둘 수 있습니다.

1 postgresql 서버의 모든 데이터베이스를 백업하십시오

충분한 공간이있는 파티션에 모든 데이터베이스를 백업하려고합니다. Linux를 사용하는 경우 gzip을 사용하여 백업을 추가로 압축하여 공간을 절약 할 수 있습니다.

su - postgres
pg_dumpall | gzip -9 > /some/partition/all.dbs.out.gz

2 구성 파일 백업

cp /path/to/postgresql/data_directory/*.conf /some/partition/

3 PostgreSQL 중지

pg_ctl -D /path/to/postgresql/data_directory stop

4 데이터 디렉토리의 내용을 삭제

rm -Rf /path/to/postgresql/data_directory/*

5 initdb를 실행하여 데이터 디렉토리를 다시 초기화하십시오.

initdb -D /path/to/postgresql/data_directory

6 구성 파일 복원

cp /some/partition/*.conf /path/to/postgresql/data_directory/*.conf 

7 Postgresql 시작

pg_ctl -D /path/to/postgresql/data_directory start

8 작성한 모든 데이터베이스의 덤프를 복원하십시오.

gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out

1
고마워, 이것은 내가 몇 가지 차이점을 가지고 결국 끝났어. 데이터베이스를 백업 한 후 방금 삭제했습니다. 그런 다음 새로운 것을 만들어 복원했습니다.
저스틴

천만에요. 데이터 디렉토리의 내용을 제거하고 initdb를 수행하는 것으로 충분하다고 생각했습니다.
Craig Efrein

훌륭하게 작동 gzip했습니다. 시간을 절약하기 위해 부품을 건너 뛰는 것이 좋습니다 .
Rafael Barbosa

17

참고 : 나는 이것을 9.1에서 테스트했습니다. 9.0 서버가 여기에 없습니다. 비록 9.0에서 작동하지만 preeeettty입니다.


주의 (@erny의 의견에서 언급 한 바와 같이) :

Note that high CPU load due to I/O operations may be expected.

임시 테이블 스페이스를 사용하여 가동 중지 시간없이이 작업을 수행 할 수 있습니다. 가동 중지 시간은 독점 잠금 형식입니다. 그러나 테이블 위에서 만 진공 청소기로 청소합니다. 따라서 클라이언트 쿼리는 해당 테이블에 액세스 때 잠금이 획득 될 때까지 기다리기만 하면됩니다 . 기존 연결을 닫을 필요는 없습니다.

그러나 테이블과 진공을 가득 채우면 독점 잠금 장치를 먼저 기다려야합니다.


먼저 추가 스토리지가 필요합니다. Stéphane의견에서 언급 했듯이 , 이것은 VACUUM FULL전체 사본보다 문제의 테이블보다 적어도 두 배 커야합니다 . 운이 좋으며 머신에 디스크를 동적으로 추가 할 수 있다면 그렇게하십시오. 에서 최악의 경우 당신은 단지 USB 디스크 (위험하고 느린하지만)를 첨부 할 수 있습니다!

그런 다음 새 장치를 마운트하고 테이블 스페이스로 사용 가능하게하십시오.

CREATE TABLESPACE tempspace LOCATION '/path/to/new/folder';

다음을 사용하여 테이블 스페이스를 쉽게 나열 할 수 있습니다.

\db

테이블의 현재 테이블 스페이스를 다시 확인하십시오 (테이블로 다시 이동할 위치를 알아야 함).

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

인 경우 NULL기본 테이블 스페이스에 있습니다.

SHOW default_tablespace;

경우 입니다 NULL뿐만 아니라, 그것은 가능성이있을 것입니다 pg_default(확인 공식 문서 가 변경된 경우 참조).

이제 테이블을 위로 이동하십시오.

ALTER TABLE mytable SET TABLESPACE tempspace;
COMMIT;  -- if autocommit is off

그것을 진공 청소기로 청소하십시오 :

VACUUM FULL mytable;

다시 옮기십시오 :

-- assuming you are using the defaults, the tablespace will be "pg_default".
-- Otherwise use the value from the SELECT we did earlier.
ALTER TABLE mytable SET TABLESPACE pg_default;
COMMIT;  -- if autocommit is off

임시 공간을 제거하십시오.

DROP TABLESPACE tempspace;

주의 : 움직임은 ... 원래 데이터 디렉토리에 더 많은 디스크 공간을 사용하는 것이 나타납니다
크리스 위더스에게

방금 9.3에서 테스트했으며 매력처럼 작동합니다.
Bartek Jablonski

9.1의 생산에 성공적으로 사용되었습니다. 테이블 공간을 변경하면 원래 사용 된 공간이 해제됩니다. I / O 작업으로 인한 높은 CPU로드가 예상 될 수 있습니다.
erny

2
이 자세한 설명에 감사드립니다. 참고 임시 테이블에 당신은 적어도해야한다는 점 size of table x 2때문에, VACUUM FULL테이블의 전체 사본을하고있다.
Stéphane

감사합니다 @ Stéphane. 정보를 본체에 추가했습니다.
exhuma

2

빠르고 더러운 :

  • Postgres 중지
  • 진공 청소기로 청소할 공간이 충분한 다른 디스크로 기본 데이터베이스 디렉토리를 이동하십시오.
  • main의 원래 위치에서 새 위치에 심볼릭 링크를 추가하십시오.
  • 진공
  • 심볼릭 링크를 삭제하고 기본 디렉토리를 원래 위치로 다시 이동하십시오.
  • Postgres 시작

예 :

$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start


0

덤프 및 복원 할 디스크 공간이있는 경우 vacuumdb --full을 수행 할 디스크 공간이 있어야합니다. 문제는 vacuumdb --full이 전체 ​​데이터 파일을 복사한다는 것입니다. 따라서 할 수있는 일은 :

  1. 큰 테이블을 보유한 파일을 다른 드라이브 (예 : 느리고 큰 드라이브)로 복사하십시오.
  2. 원래 위치에서 다른 드라이브의 새 위치로 심볼릭 링크를 만듭니다.
  3. vacuumdb --full을 실행하면 이제 다른 디스크에서 데이터를 읽고 최종 테이블을 원래 데이터 디스크에 씁니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.