Để trả lại dung lượng cho HĐH, hãy sử dụng VACUUM FULL
. Trong khi ở đó, tôi cho rằng bạn chạy VACUUM FULL ANALYZE
. Tôi trích dẫn hướng dẫn :
FULL
Chọn chân không "đầy đủ", có thể lấy lại nhiều không gian hơn , nhưng mất nhiều thời gian hơn và chỉ khóa bảng. Phương pháp này cũng cần thêm dung lượng đĩa, vì nó ghi một bản sao mới của bảng và không giải phóng bản sao cũ cho đến khi hoàn thành thao tác. Thông thường, điều này chỉ nên được sử dụng khi một lượng không gian đáng kể cần phải được thu hồi từ bên trong bảng.
Nhấn mạnh đậm của tôi.
CLUSTER
đạt được điều đó, như là một hiệu ứng tài sản thế chấp.
Plain VACUUM
thường không đạt được mục tiêu của bạn ( "một hoặc nhiều trang ở cuối bảng hoàn toàn miễn phí" ). Nó không sắp xếp lại các hàng và chỉ cắt các trang trống từ phần cuối vật lý của tệp khi có cơ hội - như trích dẫn của bạn từ hướng dẫn sử dụng.
Bạn có thể nhận được các trang trống ở cuối tệp vật lý khi bạn thực hiện INSERT
một loạt các hàng và DELETE
chúng trước khi các bộ dữ liệu khác được nối thêm. Hoặc nó có thể xảy ra do sự trùng hợp nếu đủ hàng bị xóa.
Ngoài ra còn có các cài đặt đặc biệt có thể ngăn không cho VACUUM FULL
lấy lại không gian. Xem:
Chuẩn bị các trang trống ở cuối bảng để kiểm tra
Cột hệ thống ctid
đại diện cho vị trí vật lý của một hàng. Bạn cần hiểu cột đó:
Chúng tôi có thể làm việc với điều đó và chuẩn bị một bảng bằng cách xóa tất cả các hàng từ trang cuối cùng:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
Bây giờ, trang cuối cùng trống rỗng. Điều này bỏ qua viết đồng thời. Hoặc bạn là người duy nhất viết vào bảng đó hoặc bạn cần thực hiện khóa ghi để tránh nhiễu.
Truy vấn được tối ưu hóa để xác định các hàng đủ điều kiện một cách nhanh chóng. Số thứ hai của a tid
là chỉ số tuple được lưu dưới dạng không dấu int2
và 65535
là mức tối đa cho loại đó ( 2^16 - 1
), do đó, đó là giới hạn trên an toàn.
SQL Fiddle (sử dụng lại một bảng đơn giản từ một trường hợp khác.)
Các công cụ để đo kích thước hàng / bảng:
Đĩa đầy
Bạn cần phòng ngọ nguậy trên đĩa cho bất kỳ hoạt động nào. Ngoài ra còn có công cụ cộng đồng pg_repack
thay thế cho VACUUM FULL
/ CLUSTER
. Nó tránh các khóa độc quyền nhưng cũng cần không gian trống để làm việc. Hướng dẫn sử dụng:
Yêu cầu không gian đĩa trống lớn gấp đôi so với (các) bảng đích và các chỉ mục.
Như một phương sách cuối cùng, bạn có thể chạy một chu trình kết xuất / khôi phục. Điều đó cũng loại bỏ tất cả sự phình ra từ các bảng và chỉ mục. Câu hỏi liên quan chặt chẽ:
Câu trả lời ở đây là khá triệt để. Nếu tình huống của bạn cho phép điều đó (không có khóa ngoại hoặc tham chiếu khác ngăn chặn xóa hàng) và không có quyền truy cập đồng thời vào bảng), bạn có thể chỉ cần:
Kết xuất bảng vào đĩa kết nối từ một máy tính từ xa có nhiều không gian đĩa ( -a
cho --data-only
):
Từ shell từ xa, kết xuất dữ liệu bảng:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
Trong một phiên pg, TRUNCATE
bảng:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Từ shell, khôi phục vào cùng một bảng:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Bây giờ nó là miễn phí của bất kỳ hàng chết hoặc sưng lên.
Nhưng có lẽ bạn có thể có đơn giản hơn?
Bạn có thể tạo đủ dung lượng trên đĩa bằng cách xóa (di chuyển) các tệp không liên quan không?
Bạn có thể đặt VACUUM FULL
các bảng nhỏ hơn trước, từng cái một, do đó giải phóng đủ dung lượng đĩa không?
Bạn có thể chạy REINDEX TABLE
hoặc REINDEX INDEX
để giải phóng không gian đĩa từ các chỉ mục cồng kềnh?
Dù bạn làm gì, đừng nổi mẩn . Nếu nghi ngờ, hãy sao lưu mọi thứ vào vị trí an toàn trước.