Tôi cần chạy VACUUM FULL mà không có dung lượng đĩa trống


27

Tôi có một bảng chiếm gần 90% dung lượng hd trên máy chủ của chúng tôi. Tôi đã quyết định thả một vài cột để giải phóng không gian. Nhưng tôi cần trả lại dung lượng cho HĐH. Tuy nhiên, vấn đề là tôi không chắc điều gì sẽ xảy ra nếu tôi chạy VACUUM FULL và không có đủ không gian trống để tạo một bản sao của bảng.

Tôi hiểu rằng không nên sử dụng VACUUM FULL nhưng tôi cho rằng đó là lựa chọn tốt nhất trong kịch bản này.

Có những câu chuyện mới trên trang chủ.

Tôi đang sử dụng PostgreSQL 9.0.6

Câu trả lời:


19

Vì bạn không có đủ không gian để chạy một ứng dụng trống hoặc xây dựng lại, bạn luôn có thể xây dựng lại cơ sở dữ liệu postgresql của mình bằng cách khôi phục chúng. Khôi phục cơ sở dữ liệu, bảng, chỉ mục sẽ giải phóng không gian và phân mảnh. Sau đó, bạn có thể thiết lập bảo trì tự động để làm trống cơ sở dữ liệu của bạn một cách thường xuyên.

1 Sao lưu tất cả các cơ sở dữ liệu trên máy chủ postgresql của bạn

Bạn sẽ muốn sao lưu tất cả các cơ sở dữ liệu của mình vào một phân vùng có đủ dung lượng. Nếu bạn đã sử dụng Linux, bạn có thể sử dụng gzip để nén thêm bản sao lưu để tiết kiệm dung lượng

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

2 Sao lưu tập tin cấu hình của bạn

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

3 Dừng Postgresql

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

4 xóa nội dung của thư mục dữ liệu

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

5 Chạy initdb để khôi phục lại thư mục dữ liệu của bạn

initdb -D /path/to/postgresql/data_directory

6 Khôi phục tập tin cấu hình

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

7 Bắt đầu Postgresql

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

8 Khôi phục kết xuất của tất cả các cơ sở dữ liệu bạn đã tạo

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

1
Cảm ơn, đây là những gì tôi đã làm, với một vài sự khác biệt. Tôi chỉ bỏ cơ sở dữ liệu sau khi sao lưu nó. Sau đó tạo một cái mới và khôi phục nó.
Justin

Không có gì. Tôi hình dung rằng việc loại bỏ nội dung của thư mục dữ liệu và thực hiện initdb là đủ.
Craig Efrein

Làm việc tuyệt vời, tôi chỉ khuyên bạn bỏ qua gzipphần để tiết kiệm thời gian.
Rafael Barbosa

17

LƯU Ý: Tôi đã thử nghiệm điều này trên 9.1. Tôi không có máy chủ 9.0 nằm quanh đây. Tôi chắc chắn rằng mặc dù nó sẽ hoạt động trên 9.0.


THẬN TRỌNG (Như đã lưu ý trong các nhận xét của @erny):

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

Bạn có thể làm điều này với khá nhiều thời gian không bằng cách sử dụng một vùng bảng tạm thời. Thời gian xuống sẽ ở dạng khóa độc quyền. Nhưng chỉ trên bàn bạn đang hút bụi. Vì vậy, tất cả những gì sẽ xảy ra là các truy vấn của khách hàng sẽ chỉ cần đợi khóa được lấy nếu họ truy cập vào bảng được đề cập. Bạn không cần phải đóng các kết nối hiện có.

Mặc dù vậy, một điều cần lưu ý là việc di chuyển bàn và chân không đầy đủ sẽ cần phải đợi một khóa độc quyền trước!


Đầu tiên, bạn rõ ràng cần một số lưu trữ bổ sung. Như đã Stéphaneđề cập trong các bình luận, cái này cần phải lớn hơn ít nhất gấp đôi so với bảng trong câu hỏi cũng như VACUUM FULLmột bản sao đầy đủ. Nếu bạn may mắn và có thể tự động thêm một đĩa vào máy, hãy làm điều đó. Trong trường hợp xấu nhất, bạn chỉ có thể gắn đĩa USB (mặc dù rủi ro và chậm)!

Tiếp theo, gắn thiết bị mới và làm cho nó có sẵn dưới dạng không gian bảng:

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

Bạn có thể liệt kê các không gian bảng dễ dàng bằng cách sử dụng:

\db

Kiểm tra kỹ không gian bảng hiện tại của bảng của bạn (bạn cần biết nơi để di chuyển nó trở lại):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

Nếu có NULL, nó sẽ nằm trong vùng bảng mặc định:

SHOW default_tablespace;

Nếu đóNULLtốt, nó sẽ có khả năng pg_default(kiểm tra các tài liệu chính thức trong trường hợp nó đã thay đổi).

Bây giờ di chuyển bảng qua:

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

Hút bụi:

VACUUM FULL mytable;

Di chuyển nó trở lại:

-- 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

Xóa không gian tạm thời:

DROP TABLESPACE tempspace;

Lưu ý: di chuyển dường như sử dụng nhiều dung lượng đĩa hơn trong thư mục dữ liệu gốc ...
Chris Withers

Chỉ cần thử nghiệm vào ngày 9.3 và nó hoạt động như bùa mê.
Bartek Jablonski

Sử dụng thành công trong sản xuất ngày 9.1. Sau khi thay đổi không gian bảng, không gian sử dụng ban đầu được giải phóng. Lưu ý rằng tải CPU cao do hoạt động I / O có thể được dự kiến.
erny

2
Lời khuyên tuyệt vời, cảm ơn cho lời giải thích chi tiết này. Lưu ý rằng trên không gian bảng tạm thời, bạn sẽ cần ít nhất size of table x 2, vì VACUUM FULLđang tạo một bản sao đầy đủ của bảng.
Stéphane

Cảm ơn @ Stéphane. Tôi đã thêm thông tin vào cơ thể chính.
shoutuma

2

Nhanh chóng và hèn hạ:

  • Dừng Postgres
  • Di chuyển thư mục cơ sở dữ liệu chính sang đĩa khác, nơi có đủ chỗ để hút bụi
  • Trong vị trí ban đầu của chính, thêm một liên kết tượng trưng đến vị trí mới
  • Khoảng chân không
  • Xóa liên kết tượng trưng và di chuyển thư mục chính trở lại vị trí ban đầu
  • Bắt đầu Postgres

Ví dụ,:

$ 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

Nếu bạn có không gian đĩa để thực hiện kết xuất và khôi phục, bạn nên có không gian đĩa để thực hiện chân không - đầy đủ. Vấn đề là voiddb --full sẽ tạo một bản sao của toàn bộ tệp dữ liệu. Vì vậy, những gì bạn có thể làm là:

  1. sao chép các tập tin giữ bảng lớn vào một ổ đĩa khác, ví dụ, ổ đĩa chậm hơn, lớn hơn.
  2. tạo các liên kết tượng trưng từ vị trí ban đầu đến địa điểm mới trên ổ đĩa khác.
  3. chạy chân không - đầy đủ, bây giờ nó sẽ đọc dữ liệu từ đĩa khác và ghi bảng cuối cùng vào đĩa dữ liệu gốc của bạn.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.